JVM学习

来源:互联网 发布:钢管租赁软件下载 编辑:程序博客网 时间:2024/06/05 15:07

本文参考深入理解Java虚拟机一书和http://www.importnew.com/17770.html,供作个人学习记录




程序计数器:

可以看作是当前线程所执行的字节码的行号指示器,字节码解释器的工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令,分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖这个计数器来完成。

一个处理器都会执行一条线程中的指令。因此为了线程切换后能恢复到正确的位置,每条线程都需要有一个独立的程序计数器,各线程之间计数器互不影响,独立存储,我们称这类内存区域为线程私有的内存


如果线程正在执行的是一个Java方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址;如果正在执行的是Native方法,这个计数器为空(Undefined)。此区域没有规范任何的OutOfMemoryError情况的区域。

什么是虚拟机字节码:http://www.importnew.com/13107.html


虚拟机栈

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

局部变量表

局部变量表包含了方法执行过程中的所有变量,包括this引用、所有方法参数、其他局部变量。

有这些局部变量:boolean,byte,char,short,int,float,double,reference,returnAddress,除了long和double类型以外,所有变量类型都占用局部变量表的一个位置。long和double需要占用局部变量表两个连续的位置。

操作数栈

操作数栈在执行字节指令过程中被用到,这种方式类似于原生CPU寄存器。大部分JVM字节码把时间花费数栈的操作上:入栈、出栈、复制、交换、产生消费变量的操作。因此局部变量表和操作数栈之间的交换变量指令操作通过字节码频繁执行。

动态链接

每一个栈帧都有一个运行时常量池的引用。这个引用指向栈帧当前运行方法所在类的常量池。通过这个引用支持动态链接(dynamic linking)。(待深入学习)

方法出口

(待深入学习)


Java 堆

是JVM所管理的内存中最大的一块。Java堆是被所有线程共享的一块内存区域。此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存。


方法区

它用于存储已经虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。non-heap。涉及到gc参数为-XX:MaxPermSize

运行时常量池

Runtime content pool 是方法区的一部分通过java -verbose xx.class可查看。class文件中除了有类的版本,字段,方法,接口等描述信息外,还有一项信息是常量池(Content pool table),用于存放编译期生成的各种字面量和符号引用,这部分内容将在类加载后进入方法区的运行时常量池中存放。(待深入学习)