JVM学习

Posted jaxlove-it

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JVM学习相关的知识,希望对你有一定的参考价值。

1、JVM内存模型

  技术分享图片


a、栈:

  包括虚拟机栈和本地方法栈。

  虚拟机栈为线程私有,生命周期与线程相同。java方法执行时会创建一个栈帧,里面保存着对象引用、基本类型数据等

  本地方法栈和虚拟机栈类似,虚拟机为java方法服务,为本地方法栈为Native方法服务。

b、方法区:

  方法区其中一种实现为永久代(PermGen),他是所有线程共享的区域,里面保存着类信息、静态变量、常量等。

c、堆(heap):

  所有线程共享区域,里面保存着对象和数组(java8开始静态变量和常量也保存在堆中)

d、PC寄存器(程序计数器):

  线程私有,记录着每个线程运行的位置

e、元空间(Metaspace):

  从java1.7开始,永久代里的数据有一部分数据开始移到堆中保存了,到了java1.8,永久代已经完全移除,取而代之的是元空间。他的作用类似永久代

 

2、个别内存区域的单独介绍

a、堆:

  堆内存分为新生代(伊甸园eden、幸存区from Survivor -to Survivor )和老年代。堆数据优先保存在eden区,大对象直接进去老年区。当jvm经历了Minor Gc时,对象从eden区移至Survivor区。当对象在Survivor经历了MaxTenuringThrehold-1(从Eden到Survivor已经经历了1次)次后仍然存活,对象移至老年代。

b、元空间:

  java8开始,jvm不在支持PermSize和MaxPermSize参数配置永久代。但是可以通过 -XX:MetaspaceSize和 -XX:MaxMetaspaceSize(可防止元空间占用太多本地内存)来配置元空间大小。

  元空间与永久代最大的区别是:元空间不在虚拟机中,而在本地内存中。同时原来的常量移到了堆中的运行时常量池,静态变量也移到堆中了,因此java8中的堆内存会比以前大很多

  由于永久代每次FullGc都会使永久代数据移动,同时类信息的大小比较难以确定等原因,使得永久代大小也难以确定。因此永久难以调优。元空间有元空间虚拟机管理,同时可以动态管理元空间大小。节约了GC扫描和压缩时间。

 

3、对象已死:

  a、引用计数法:给对象引用加一个计数器,当一个地方引用它一次,加1,引用失效时,减1,为0时则对象已死。

    缺点:当实例相互引用时,无法判断是否为已死

  b、根搜索算法:GcRoots不可达时,已死。(通过一系列名为"GC Roots"的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链(Reference Chain),当一个对象到GC Roots没有任何引用链相连时)

 

4、垃圾回收算法

a、标记-清除:

  缺点:标记和清除的效率都不高,以及标记清除后会产生大量的内存不连续的碎片

b、复制算法:

  介绍:把内存分为俩快,一个内存满时,将活的对象移动的另一个内存,将满的内存清空

  缺点:浪费空间

  ps:eden -> survivor使用的就是复制算法,当eden区存活率高时,使用老年代空间(伊甸园和幸存区默认空间比例8:1)

    fromSurvivor -> toSurvivor也使用的是复制算法

c、标记-整理算法:

  与标记-清除算法一样,但是这个是标记后让所有存活的对象移到一端,然后清空另一端

d、分代收集算法:

  根据不同的区使用不同的回收机制

  ps:一般分为新生代和老年代,新手代存活率低使用复制算法,老年代存活率高使用标记清除或者标记整理算法。

 

5、FullGc的条件

a、System.gc()方法调用

b、老年代空间(old/Tenured)不足 

c、永生代(元空间)空间不足

d、CMS GC时出现promotion failed和concurrent mode failure 

e、统一Minor Gc晋升到老年代的平均值大于老年代的剩余空间

f、堆中分配很大的对象,老年代中没有足够的连续空间保存该大对象

 

6、垃圾回收器

  垃圾回收有很多类型,这个主要回顾一下CMS和G1

a、CMS:

技术分享图片

 

 

  优点:减少程序的停顿时间(但是在初始标记和重新标记时依然会发生 stop the world)

   缺点:由于在gc时,程序仍然在运行,这导致垃圾回收并不一定完全,甚至可能发生错误导致执行fullGC,同时这也导致cms的回收频率比较高,影响应用程序的吞吐量(要求CPU)

b、G1 

  g1回收器将堆空间划分为多个区域(即会有个多个Eden、多个Survivor、多个old区、多个Humongous区(用于保存大对象的区域))

  g1回收器或在第一时间处理垃圾最多的区域,虽然也会暂停应用,但是会花费较少的时间回收垃圾最多的区域。

  g1与CMS相比的优点:1、因为划分为多个区域,回收时减少了内存碎片的产生。2、g1适用与新生代和老年代,CMS只适用用老年代。

 

  

 

  

  

 






以上是关于JVM学习的主要内容,如果未能解决你的问题,请参考以下文章

JVM学习--垃圾回收机制

JVM学习--JVM运行时数据区图文详解

JVM 内存结构 -- 什么是JVM学习JVM的好处学习路线(JVM的组成)程序计数器虚拟机栈(栈内存溢出线程运行诊断)

JVM学习

小白学习JVM--概述和模型

JVM基础:深入学习JVM堆与JVM栈(转)