现在的位置: 首页 > 综合 > 正文

《深入java虚拟机–JVM高级特性与最佳实践》学习笔记(二) JAVA虚拟机运行时数据区

2013年12月09日 ⁄ 综合 ⁄ 共 969字 ⁄ 字号 评论关闭

1. 程序计数器

可看成是当前线程所执行的字节码的行号指示器,通过改变计数器的值来选取下一条要执行的字节码指令,分支、循环、跳转、异常处理、恢复等基础功能都需要依赖这个计数器来完成。线程私有,互不影响,独立存储。

如果当前执行的是JAVA方法,计数器指向字节码指令地址。如果执行的是native方法,计数器中无值。

2. JAVA虚拟机栈

每个方法执行的时候会创造一个栈帧(Stack Frame)用于存储局部变量表、操作数栈、动态链接、方法出口等信息。每个方法调用纸质执行完成的过程,对应一个栈帧在虚拟机栈中从入栈到出栈的过程。

两种异常:

        线程请求栈深度超过栈目前深度(Stack Over Flow Error);

        虚拟机栈自动扩张时无法申请到空间(Out Of Memory Error)。

3. 本地方法栈

类似JAVA虚拟机栈,但为Native方法服务。Sun HotSpot虚拟机把本地方法栈和虚拟机栈合并了。

4. Java堆

线程共享,几乎所有的对象在堆上分配(JIT编译器的发展与逃逸分析技术的逐渐成熟,栈上分配、标量替换优化技术将会导致“对象都分配在堆上”不这么绝对了)。

GC管理的主要区域,细分成新生代和老年代,新生代又分成Edon,From Survivor,To Survivor。

JAVA堆可以处在物理上不连续的内存空间中,只要逻辑连续就可以。可以是固定大小也可以是可扩展的(-Xms,-Xmx)。

5. 方法区

线程共享,用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。和堆一样不需要连续内困且可固定大小或扩展。内存回收条件苛刻。

6. 运行时常量池(含在方法去区里面)

存放编译器生成的各种字面量和符号引用(翻译出来的直接引用也存在这里)。String的intern()就是用于重用此池之中的内容。

7. 直接内存

不是虚拟机运行时数据区的一部分,也不再虚拟机规范中定义,但频繁的使用。JDK1,.4之中引入了NIO,引入了一种基于通道(Channel)和缓冲区(Buffer)的I/O方式,他可以使用Native函数库直接分配堆外内存,然后通过一个存储在JAVA对里面的DirectByteBuffer对象作为这块内存的引用进行操作。这避免了JAVA堆与Native堆来回复制数据,在一些场景中可以先出提高性能。

抱歉!评论已关闭.