深入理解JAVA虚拟机学习笔记之垃圾回收

JVM调优总结:http://unixboy.iteye.com/blog/174173/

JVM内存分配、GC原理、垃圾收集器:http://www.importnew.com/23035.html

 

1. VM参数设置打印GC详细信息

-verbose:gc (开启打印垃圾回收日志)

-Xloggc:D:testgc.log (设置垃圾回收日志打印的文件,文件名称可以自定义)

-XX:+PrintGCTimeStamps (打印垃圾回收时间信息时的时间格式)

-XX:+PrintGCDetails (打印垃圾回收详情)

2. 回收算法

   1) 引用计数算法

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

缺点:很难解决对象之间相互循环引用的问题。

   2) 根搜索算法(可达性分析法)

通过一系列名为GC Roots的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径成为引用链,当一个对象到GC Roots没有任何引用链相连时,则证明此对象不可用。

可以作为GC Roots的对象包括下面几个:

        a. 虚拟机栈中引用的对象

        b. 方法区中的类静态属性引用的对象

        c. 方法区中的常量引用的对象

        d. 本地方法栈中JNI的引用的对象

总结就是,方法运行时,方法中引用的对象;类的静态变量引用的对象;类中常量引用的对象;Native方法中引用的对象。

 两次标记过程:

           1) 根搜索确认对象没有与GC Roots链接的引用链

           2) 第一次标记对象并进行筛选,筛选条件是此对象是否有必要执行finalize()方法(未覆盖或者已执行finalize方法的对象将不会被选中)。

           3) 筛选中的对象放入F-Queue中。

           4) GC对F-Queue中对象进行二次小规模标记,若对象在finalize方法中重新连接引用链,则对象移除出回收集合。

           5) 二次标记的对象将会被清理。

总结:任何一个对象的finalize方法都只会被系统自动调用一次,如果对象面临下一次回收,则finalize方法不会被再次执行。

 

3. 引用

   1) 强引用:只要强引用存在,GC不会回收被引用的对象。

   2) 软引用:系统将要发生内存溢出异常之前,将弱引用列入回收范围之中并进行第二次回收。

   3) 弱引用:被弱引用关联的对象只能生存到下一次垃圾收集发生之前。

   4) 虚引用:对象是否存在虚引用对其生存没有任何影响,无法通过虚引用获取对象实例。虚引用的作用就是利用这个对象在被回收时收到一个系统通知。

4. 垃圾收集算法

  1) 标记-清除算法

逻辑:标记所有需要回收的对象,标记完成后收回所有标记对象。

缺点:效率问题,标记清除效率都不高;空间问题,标记清除后会产生大量不连续的内存碎片。

  2) 复制算法

可用内存分大小相等两块,每次使用一块,当使用完时将活着的对象复制到另一块上,然后把已使用的空间一次清理。

优点:实现简单,运行高效,却不会存在碎片问题。

缺点:可用内存缩小一半,空间代价太高。

  3) 标记-整理算法

标记所有需要回收的对象,将活着的对象向一端移动,边界之外的内存全部清理掉。

  4) 分代收集算法

java堆分为新生代和老年代,新生代垃圾回收后剩余活着的对象移到老年代,老年代中的对象采用标记整理或者标记清除算法回收。

 

5. JVM堆分代管理

   1) JAVA堆分为两块区域:新生代和老年代。堆大小=新生代+老年代。(一般情况下新生代占堆空间的1/3,老年代占2/3)。

   2) 新生代又分为Eden、survivor(from), survivor(to),一般比例是8:1:1。

   3) 新生代GC(Minor GC):新生代的垃圾收集动作。老年代GC(MajorGC/Full GC)指的是老年代的垃圾收集动作。MajorGC的速度一般比MinorGC的速度慢10倍以上。

   4) 新生代中使用的垃圾回收算法是复制算法,老年代中使用的是标记整理算法。

   5) 新生代几乎是所有java对象出生的地方,有时候大对象会直接在老年代中分配(-XX:PretenureSizeThreshold参数设置,多大的对象直接在老年代中分配),其分配过程描述如下:

       a. 初始时对象只存在于Eden区和survivor(from)区,survivor(to)区是空的。

b. 第一次MinorGC后,Eden区所有存活的对象复制到to中,而from中仍然存活的对象会根据他们的年龄决定去向,年龄达到一定值(年龄阈值,通过-XX:MaxTenuringThreshold设置)的对象会被移动到老年代中。每个对象坚持过一次MinorGC后,年龄增加1.

c. Eden区已被清空,from区也被清空。此时from和to会交换角色,保证to区是空的。

d. 循环MinorGC,当To区无法容纳更多的对象时,将会把to区中的对象全部移到老年代中。

   6) 空间分配担保

        发生minorGC时虚拟机会检测之新生代所有对象的大小与老年代中最大连续可用空间的大小,如果小于,则改为直接进行一次FullGC, 如果小于,则查看HandlePromotionFailure设置是否允许担保失败; 如果允许,则判断老年代剩余连续最大可用空间的大小与之前晋升到老年代对象的平均大小比较,如果大于则进行一次MinorGC,如果小于或者HandlePromotionFailure担保失败则改为进行一次FullGC.

     JVM参数:-XX:HandlePromotionFailure开启是否进行担保。

   7) 有关JVM参数:

a)-XX:NewSize和-XX:MaxNewSize

用于设置年轻代的大小,建议设为整个堆大小的1/3或者1/4,两个值设为一样大。

b)-XX:SurvivorRatio

用于设置Eden和其中一个Survivor的比值,这个值也比较重要。

c)-XX:+PrintTenuringDistribution

这个参数用于显示每次Minor GC时Survivor区中各个年龄段的对象的大小。

d).-XX:InitialTenuringThreshold和-XX:MaxTenuringThreshold

用于设置晋升到老年代的对象年龄的最小值和最大值,每个对象在坚持过一次Minor GC之后,年龄就加1。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值