JVM系列(三) : 运行时数据区
1、jvm分类
1.1.Hotspot VM 是之前使用最广泛的Java虚拟机,
1.2.JRockit VM 是BEA 开发的一款虚拟机是 号称 "运行最快的java虚拟机"、
1.3.J9 VM 是IBM开发的一款虚拟机
1.4.Dalvik Vm 是Google 开发的一款移动端虚拟机
1.5 TaobaoVm 是阿里巴巴研发团队开发的一款虚拟机
总结: 现在OEACLE 收购了 SUN 和 BEA 将HotSpot 和JRockit 两款虚拟机合并
2、jvm 运行时数据区
2.1.jvm 在运行过程中会将它管理的内存划分成若干个不同的区域
线程共享:堆、方法区
线程私有: 程序计数器、虚拟机栈,本地方法栈
2.2.程序计数器
程序计数器(Program Counter Register)是一块较小的内存空间,是指向当前线程正在执行的字节码指令的地址或者行号
因为java是多线程和cup时间片轮转机制算法,导致线程上下文切换,所以当线程恢复运行的时需要保证程序的正常运行,需要记录之前线程运行的位置
如果线程执行java方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址,如果执行的是native方法,计数器的值为undefined
程序计数器也是jvm中唯一不会发生OOM(OutOfMemory)的区域
2.3.虚拟机栈
特点:是先进后出、入口和出口只有一个栈,是一种数据结构
定义:存储当前线程运行方法所需的数据、指令、返回地址
虚拟机栈的大小缺省为 1M, 可用参数 –Xss 调整大小, 例如-Xss512k
参数官方文档(JDK1.8) : https://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html
线程在运行的时候会给每个方法创建一个栈帧、栈帧包括:操作数栈、局部变量表、返回地址、动态链接
2.4.方法区或者元空间
存储类信息(字节码)、常量、静态变量,
JDK1.7以前叫方法区,通过 -XX:PermSize 和-XX:MaxPermSize 设置其大小
JDK1.8之后叫元空间,通过-XX:MetaspaceSize 和-XX:MaxMetaspaceSize,
-XX:MaxMetaspaceSize: 设置元空间最大值, 默认是-1, 即不限制, 或者说只受限于本地内存大小,-XX:MetaspaceSize: 指定元空间触发Fullgc的初始阈值(元空间无固定初始大小), 以字节为单位,默认是21M,达到该值就会触发full gc进行类型卸载,一般建议在JVM参数中将MetaspaceSize和MaxMetaspaceSize设置成一样的值,并设置得比初始值要大
修改方法区为元空间的是因为方法区存储类,常量、静态变量容易出现内存溢出、对元空间的调用很难优化,
同时将元空间和堆的垃圾回收进行隔离、避免进行Full GC和OOM
2.5.堆
存储实例变量,对象 通过参数-Xms 和-Xmx 设置其大小
常量池中存放的是字面量
JDK1.6以前常量池是在方法区中
JDK1.7以后常量池存放在堆中