认识JVM

来源:互联网 发布:c 网络编程基础 编辑:程序博客网 时间:2024/05/21 22:29

1,jvm内存模型


年轻代(young generation)

      1,年轻代是所有新对象产生的地方,当年轻代内存空间被用完时,就会触发垃圾回收,这个叫做minor gc .年轻代划分为3个部分

         Eden   survivor0  survivor1  (Hotspot 中 Eden:survivor比例8:1)

老年代(old generation)

      1,年老代内存包含长期存活的对象和进过多次minor gc 后依然存活下来的对象。老年代内存被占满时进行垃圾回收 叫做major gc

永久代(perm generation)

      1,永久代包含了jvm需要的应用元数据,这些元数据描述了在应用里使用的类和方法,注意永久代不是Java堆内存的一部分

方法区是永久代空间的一部分,用来存储类型信息 运行时常量,静态变量,方法和构造函数代码

判断对象是否存活

       1.引用计数法

           给对象中添加一个引用计数器,每当有一个地方引用它时,计数器值就加1;当引用失效时,计数器值就减1;任何时刻计数器为0的对象就是不可能再被使用的。

           jvm 没有使用计数器算法来管理内存,其中主要原因是它很难解决对象之间相互循环引用的问题。

       2.可达性分析

           从GC ROOTS 开始向下搜索,搜索所走过的路径称为应用链。当一个对象到gc roots 没有任何应用链相连时,则证明此对象是不可用的。

gc 算法

  1.标记-清除(Mark sweep)

     首先标记出所有需要回收的对象,在标记完成后统一回收掉所有被标记的对象。

      要点:效率不高、产生大量不连续的内存碎片

   2.复制(copying)

     将内存按容量划分大小相等的两块,每次只是用其中一块。当这一块的内存用完了,就将还存活的对象复制到另外一块上面,然后再把已使用过的内存空间一次清理掉。

     要点: 效率高、 代价将内存缩小为原来的一半,持续复制存活率高的对象则导致效率降低。现在大部分虚拟机都采用这个算法进行新生代的回收。

   3.标记-整理(mark compact)

     标记-整理与标记-清除类似,只是后续部分不是直接对可回收对象进行清理,而是让所有存活的对象都向一端移动,然后直接清理掉端边界意外的内存。

   4.分代收集算法(generational collection)

     分代收集只是根据对象存活周期的不同将内存划分几块。 把Java堆分为新生代和老年代,这样就可以根据各个年代的特点采用最适合的收集算法。在新生代中,每次垃圾收集时都发现有大批对象死去,只有少量存活,那就选用复制算法,只需要付出少量存活对象的复制成本就可以完成收集。而老年代中因为对象存活率高,没有额外空间进行对它进行分配担保,就必须使用标记-清理 或者 标记-整理算法进行回收。


gc 垃圾收集器(基于Hotspot)

两个概念:

并行:指多条垃圾收集线程并行工作,但此时用户线程仍然处于等待状态。

并发:指用户线程与垃圾收集线程同时执行,用户程序在继续运行,而垃圾收集程序运行于另一个cpu上。


   Serial 收集器

   参数 -XX:+UseSerialGC  它的“单线程” 不仅仅说明它只会使用一个cpu 或一条收集线程去完成垃圾收集工作,更重要的是它进行垃圾收集时,必须暂停其他所有的工作线程,直到它收集结束。

   ParNew 收集器

    其实就是serial 收集器的多线程版本。新生代收集的首选 目前只有它能与cms收集器配合使用。ParNew 收集器也是使用-XX:+UseConcMarkSweepGC选项后的默认新生代收集器,也可以使用-XX:+UseParNewGC选项来强制指定。默认开启的收集线程数与CPU的数量相同,也可以使用 -XX:+ParallelGCThreads参数来限制。

  Parallel 收集器

     使用复制算法的收集器,并行多线程收集器,但它的目标则是达到一个可控制的吞吐量(吞吐量=运行用户代码时间/(运行用户代码时间+垃圾收集时间))

 Serial old 收集器

     Serial收集器的老年代版本,单线程使用“标记-整理”算法。

  parallel old 收集器

     是Parallel Scavenge收集器的老年代版本,使用多线程 标记-整理 算法, 吞吐量优先使用  采用 新生代 Parallel Scavenge 老年代采用parallel old。

  cms 收集器

     该收集器是一种以获得最短回收停顿时间为目标的收集器。基于标记-清除实现的 分4个步骤 初始标记-》并发标记-》重新标记-》并发清除

    对CPU资源比较敏感,无法处理浮动垃圾,还会产生大量空间碎片

   常伴随着 -XX:CMSInitiatingOccupancyFraction 参数老年代百分比时进行回收

                   -XX:+UseCompactAtFullCollection (默认开启)进行FullGC时开启内存碎片合并整理

                   -XX:CMSFullGCsBeforeCompaction 参数用于设置执行多少次不压缩的FUll GC后 跟随来一次带压缩Full GC

  g1收集器

    使用g1收集器时,Java堆的内存布局就与其他收集器有很大区别,他将整个Java堆划分为多个大小相等的独立区域,没怎么使用过。后续用了再来补充。


gc 异常排查

   以后再补充吧



gc 常用命令

  jps   显示指定系统内所有的Hotspot虚拟机进程

  jinfo  显示虚拟机配置信息

  jstat 用于收集Hotspot虚拟机各方面运行数据

  jmap 生产虚拟机的内存转存快照

  jhat  用于分析转存快照

  jstack  显示虚拟机的线程快照


gc日志分析


53.092: [GC53.092: [ParNew: 838912K->50004K(943744K), 0.0831020 secs] 838912K->50004K(4089472K), 0.0832400 secs] [Times: user=0.34 sys=0.02, real=0.09 secs] 


7204.738: [Full GC7204.739: [CMS: 329067K->317488K(3145728K), 1.9303260 secs] 1074227K->317488K(4089472K), [CMS Perm : 37058K->37043K(262144K)], 1.9305540 secs] [Times: user=1.93 sys=0.00, real=1.93 secs]

53.092  7204.738  指从Java虚拟机启动以来经过的秒数。

[GC  、[Full GC 说明了这次垃圾收集的停顿类型,full 说明这次GC发生了stop-the-world 

[ParNew  [CMS  GC发生的区域与垃圾收集器有关

838912K->50004K(943744K) 表示 GC前该内存区域已使用容量->GC后该内存区域已使用的容量(该内存区域总容量)


 方括号外的 838912K->50004K(4089472K)   表示 GC 前Java堆内存已使用容量->GC后Java堆已使用容量(Java堆总容量)

0.0832400 secs 表示该内存区域GC所占用的时间单位秒。


   


 



原创粉丝点击