`

《深入理解Java虚拟机》笔记之第2章 Java内存区域与内存溢出异常

阅读更多

 

1Java虚拟机运行时的数据区域,如下图所示。

     

(1)  程序计数器

    每个线程都有一个独立的程序计数器,该内存区域不会出现OutOfMemoryError

(2)  Java虚拟机栈

线程私有,生命周期与线程相同。虚拟机栈描述的是Java方法执行的内存模型:每个方法被执行的时候都会同时创建一个栈帧(Stack Frame)用于存储局部变量表、操作数栈、动态链接、方法出口等信息。每一个方法被调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。

局部变量表存放了编译期可知的各种基本数据(booleanbytecharshortintfloatlongdouble)、对象引用和returnAddress类型。局部变量表也就是人们常说的栈内存(Stack)。

(3)  Java

所有线程共享,Java虚拟机启动时创建,通常是Java虚拟机所管理的内存中最大的一块。Java虚拟机规范说:所有的对象实例以及数据都要在堆上分配(栈上分配、标量替换等优化技术例外)。

线程共享的java堆中可能划分出多个线程私有的分配缓冲区(Thread Local Allocation BufferTLAB)

Java堆可以处于物理上不连续的内存空间中,只要逻辑上是连续的即可。

Java堆还可以细分为新生代和老年代。

(4) 方法区

线程共享,用于存储已被机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。 方法区也被称为“永久代”,垃圾收集行为在这个区域也比较少。

运行时常量池(Runtime Constant Pool)也是方法区的一部分。

(5) 直接内存(Direct Memory

 

直接内存并不是虚拟机运行时数据区的一部分,也不是java虚拟机规范中定义的内存区域,但仍然会出现导致OutOfMemoryError出现(如忽略掉直接内存,导致各个内存区域的总和大于物理内存限制)

 

2、对象访问举例

Object obj = new Object();

 

“Object obj”这部分语义将会反映到Java栈的本地变量表中,作为一个reference类型数据出现。而“new Object()”这部分的语义将会反映到java堆中,形成一块存储了Object类型所有实例数据值(Instance Data,对象中各个实例字段的数据)的结构化内存。另外,在java堆中还必须包含能查到此对象类型数据(如对象类型、父类、实现的接口、方法等)的地址信息,这些类型数据则存储在方法区中。

  • 大小: 109.4 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics