Java内存区域

cgkelei 5年前
   <p>Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域。不同的区域有不同的用途,它们的创建和销毁的时间点也有不同,这个就是该篇文章所要讲述的内容。</p>    <p><strong>运行时数据区域</strong></p>    <p>由所有线程共享的数据区域:方法区、Java堆。这些区域随着虚拟机的启动而生成。</p>    <p>线程隔离的数据区域:本地方法栈、Java虚拟机栈、程序计数器。这些区域依赖用户线程的启动和结束来建立和销毁。</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/a25f1778836017e955c29bd6750b949e.png"></p>    <p style="text-align:center">运行时数据区域.png</p>    <p><strong>1、Java堆( Java Heap )</strong></p>    <p>Java堆唯一的目的是存放对象实例和数组。同时,Java堆也是垃圾收集器管理的主要区域,很多时候也称为 <strong> GC堆( <em>Garbage Collected Heap</em> ) </strong></p>    <p><strong>2、方法区( Method Area )</strong></p>    <p>方法区用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。Java虚拟机规范将方法区描述为堆的一个逻辑部分,但是它却有一个别名叫做 <strong>Non-Heap</strong> ,目的应该是与Java堆区分开来。</p>    <p>方法区中还有一个特殊的部分 —— <strong>运行时常量池</strong> 。Class文件除了有类的版本、字段、方法、接口等描述信息外,还有一项信息是 <strong>常量池(Constant Pool Table)</strong> ,用于存放编译期生成的各种字面量和符号引用,这部分内容在类加载后存放到方法区的运行时常量池中。</p>    <p>运行时常量池另外一重要特征是动态性,Java语言并不要求常量一定只能在编译期间产生,运行期间也可能将新的常量放入池中,这种特性可以体现在 String 类的 intern() 方法</p>    <p><strong>3、Java虚拟机栈( Java Virtual Machine Stacks )</strong></p>    <p>虚拟机栈描述的Java方法执行的内存模型:每个方法被执行的时候都会同时创建一个 <strong> 栈帧( <em>Stack Frame</em> ) </strong> 用于存储局部变量表、操作栈、动态链接、方法出口等信息。每个方法被调用的过程对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。</p>    <p><strong>4、本地方法栈( Native Method Stacks )</strong></p>    <p>本地方法栈与虚拟机栈功能相似,区别在于虚拟机栈执行Java方法(也就是字节码)服务,而本地方法栈则是为虚拟机使用到的Native方法服务。一些虚拟机(例如:Sun HotSpot虚拟机)直接把本地方法栈与虚拟机栈合二为一。</p>    <p><strong>5、程序计数器( Program Couter Register )</strong></p>    <p>程序计数器可以看做是当前线程所执行的字节码的行号指示器。所以在执行Java方法与Native方法的时候程序计数器的处理方式不一样:</p>    <p>如果线程正在执行的是一个Java方法,这个计数器记录的是正在执行的虚拟机字节码的地址;如果正在执行的Native方法,这个计数器值则为空。</p>    <p> </p>    <p> </p>    <p>来自:http://www.jianshu.com/p/90a9647b02f2</p>    <p> </p>