JVM学习笔记(一)——JAVA内存区域
最近开始学习JVM,在此把学习中的体会记录下来。资料主要来源是《深入理解JAVA虚拟机》这本书,以及一些网上找的其他资料。目标JVM是HotSpot
1、JAVA运行时数据区包括程序计数器、堆、虚拟机栈、本地方法栈、方法区
2、内存区域可以分为“线程私有”和“线程共享”2种。比如程序计数器是属于线程私有的,为了在线程切换之后能恢复到正确的执行位置,每条线程都需要有一个独立的程序计数器;而堆是线程共享的
3、程序计数器是一块较小的内存空间,可以看作是当前线程执行的字节码的行号指示器。如果线程正在执行一个JAVA方法,该计数器记录的是正在执行的虚拟机字节码指令的地址;如果正在执行一个NATIVE方法,该计数器值为空
4、虚拟机栈也是线程私有的,生命周期与线程相同
5、虚拟机栈描述的是JAVA方法执行的内存模型:每个方法被执行的时候都会同时创建一个栈帧,用于存储局部变量表、操作栈、动态链接、方法出口等信息。每一个方法被调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程
6、虚拟机栈中的局部变量表,存放编译期可知的各种基本数据类型、对象引用和returnAddress类型
7、本地方法栈与虚拟机栈类似,区别在于虚拟机栈为JAVA方法(也就是字节码)服务,而本地方法栈为虚拟机用到的NATIVE方法服务
8、鉴于本地方法栈和虚拟机栈十分相似,HotSpot直接将本地方法栈和虚拟机栈合二为一
9、JAVA堆是线程共享的内存区域,在虚拟机启动时就创建。该内存区域的唯一目的是存放对象实例,几乎所有的对象实例都在这里分配内存
10、JAVA堆也是垃圾收集器管理的主要区域,所以有时也被称为GC堆。JAVA堆可以细分为新生代和老年代;也可以进一步细分为Eden空间、From Survivor空间、To Survivor空间
11、方法区也是线程共享的内存区域。它用于存放已经被虚拟机加载的类信息、常量、静态变量、JIT编译器编译后的代码等数据。虽然JAVA虚拟机规范将方法区描述为堆的一个逻辑部分,但是它却有一个别名叫NonHeap,目的应该是与JAVA堆区分开来
12、方法区的内存回收目标主要是针对常量池的回收和对类型的卸载
13、运行时常量池是方法区的一部分。Class文件除了有类的版本、字段、方法、接口等描述信息外,还有一项信息是常量池,用于存放编译期生成的各种字面量和符号引用,这部分内容在类加载之后存放到方法区的运行时常量池中
14、即使是最简单的访问,也会涉及JAVA栈、JAVA堆、方法区这3个最重要的内存区域之间的关联关系
Object obj = new Object();

