首页 > 技术文章 > JVM系列(三) : 运行时数据区

huyang0726 2019-11-24 18:36 原文

 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以后常量池存放在堆中      

推荐阅读