JVM(一) ---JVM的数据模型
jvm的逻辑内存模型图
[逻辑内存模型图]
-----
jvm内部分区
其实jvm内部不仅仅只有栈和堆
包括 程序计数器 、 java 虚拟机栈 、本地方法栈、java 堆、方法区等
1. 程序计数器
线程私有,较小的内存空间,如果线程正在执行的是一个java 方法,这个计数器记录的是正在执行的虚拟机字节
码指令的地址;如果正在执行的是natvie 方法,这个计数器值则为空(undefined)。此
内存区域是唯一一个在java 虚拟机规范中没有规定任何outofmemoryerror 情况的区域。
2. java 虚拟机栈(栈区)
线程私有,每个方法被执行的时候都会同时创建一个栈帧用于存储局部变量表、操作栈、动态
链接、方法出口等信息。每一个方法被调用直至执行完成的过程,就对应着一个栈帧在
虚拟机栈中从入栈到出栈的过程。
3.本地方法栈
与虚拟机栈所发挥的作用是非常相似的,区别不过是虚拟机栈为虚拟机执行java 方法(也就是字节码)服务,
而本地方法栈则是为虚拟机使用到的native 方法服务,有的虚拟机(譬如sun hotspot 虚拟机)直接就把本地方法栈和虚拟机栈合二为一。
与虚拟机栈一样,本地方法栈区域也会抛出*error 和outofmemoryerror
4.java 堆(堆区)
线程共享,此内存区域的唯一目的就是创建并存放对象实例,也是gc区。分代收集算法:内存区大概分为新生代,老年代,永久代。
新生代从eden区创建,复制到survivor区(2个 from 和 to)。 gc分为minor gc 和 full gc ,
minor gc: eden满了就触发minor gc,minorgc会将eden区仍然存活的会复制到tosurvivor
,fromsurvivor一部分复制到老年代,一部分复制到tosurvivor,此时原eden和from的数据清空,from和to互换,这样的过程直到to被填满,复制到老年代。
fullgc:(1)年老代内存不足;(2)持久代内存不足;(3)统计得到的minor gc晋升到旧生代的平均大小大于旧生代的剩余空间(4)调用system.gc()方法的时候,
5. 方法区(类级/静态)
线程共享,存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。
虽然java 虚拟机规范把方法区描述为堆的一个逻辑部分,但是它别名叫做non-heap(非堆)
即“永久代”,不进行gc,只是针对常量池的回收和对类型的卸载
运行时常量池:是方法区的一部分,class常量池存放编译期生成的各种字面量和符号引用,
运行时常量池相对于class 文件常量池的另外一个重要特征是具备动态性,运行期间也可能将新的常量放入池中,这种特性被开发
人员利用得比较多的便是string 类的intern() 方法(这个方法会首先检查字符串池中是否有”ab”这个字符串,如果存在则返回这个字符串的引用,
否则就将这个字符串添加到字符串常量池中,然会返回这个字符串的引用,这可以实现字符串的"= ="比较。new string 不进入常量池,直接赋值会进入常量池)。