JVM--05 Java内存区域介绍

摘抄自小涛涛~~~:小涛涛JVM系列博客

JAVA虚拟机内存模型如下图所示:

        上图我们可以看到JAVA虚拟机内存模型分为两大块:线程共享区和线程独占区域。

        线程共享区:方法区和堆是分配给进程的,也就是所有线程共享的。

        线程独占区:栈和程序计数器,则是分配给每个独立线程的,是运行过程中必不可少的资源。

其中对各个模块详细解释如下:

1、方法区(Method Area)

        方法区(Method Area)与Java堆一样,是各个线程共享的内存区域,它用于存储已被虚拟机加载的类信息、常量、静态

变量、即时编译器编译后的代码等数据。虽然Java虚拟机规范把方法区描述为堆的一个逻辑部分,但是它却有一个别名叫做

Non-Heap(非堆),目的应该是与Java堆区分开来。

2、程序计数器(Program Counter Register)

        程序计数器(Program Counter Register)是一块较小的内存空间,它的作用可以看做是当前线程所执行的字节码的行号

指示器。在虚拟机的概念模型里(仅是概念模型,各种虚拟机可能会通过一些更高效的方式去实现),字节码解释器工作时就是

通过改变这个计数器的值来选取下一条需要执行的字节码指令,分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖

这个计数器来完成。

3、栈(Stacks)

        在Java中,JVM中的栈记录了线程的方法调用。每个线程拥有一个栈。在某个线程的运行过程中,如果有新的方法调用,那

么该线程对应的栈就会增加一个存储单元,即帧(frame)。在frame中,保存有该方法调用的参数、局部变量和返回地址。

        Java的参数和局部变量只能是基本类型的变量(比如int),或者对象的引用(reference)。因此,在栈中,只保存有基本类型的

变量和对象引用。引用所指向的对象保存在堆中。(引用可能为Null值,即不指向任何对象)。

        当被调用方法运行结束时,该方法对应的帧将被删除,参数和局部变量所占据的空间也随之释放。线程回到原方法,继续执

行。当所有的栈都清空时,程序也随之运行结束。

        本地方法栈与虚拟机栈的区别:

        本地方法栈(Native Method Stacks)与虚拟机栈所发挥的作用是非常相似的,其区别不过是虚拟机栈为虚拟机执行Java

方法(也就是字节码)服务,而本地方法栈则是为虚拟机使用到的Native方法服务。虚拟机规范中对本地方法栈中的方法使用的

语言、使用方式与数据结构并没有强制规定,因此具体的虚拟机可以自由实现它。甚至有的虚拟机(譬如Sun HotSpot虚拟机)

直接就把本地方法栈和虚拟机栈合二为一。与虚拟机栈一样,本地方法栈区域也会抛出StackOverflowError和

OutOfMemoryError异常。

4、堆(Heap)

        堆是JVM中一块可自由分配给对象的区域。当我们谈论垃圾回收(garbage collection)时,我们主要回收堆(heap)的空间。

        Java的普通对象存活在堆中。与栈不同,堆的空间不会随着方法调用结束而清空。因此,在某个方法中创建的对象,可以在

方法调用结束之后,继续存在于堆中。这带来的一个问题是,如果我们不断的创建新的对象,内存空间将最终消耗殆尽。

猜你喜欢

转载自blog.csdn.net/PORSCHE_GT3RS/article/details/82356396