JVM 第三章垃圾回收部分摘抄

我们要怎么理解这里说的引用呢?
  1. 强引用:new Object() ,只要强引用还在,就不能GC
  2. 软引用:系统将要内存溢出异常,这之前将对象列入回收范围,二次回收。
  3. 弱引用:只能生存到下次GC之前,无论内存是否充足。
  4. 虚引用:相同虚设、对象与之关联的目的是:在本对象被GC时收到一个系统通知。
Be or Die ???可达性分析中:“一定非死不可么?,有没有可能逃脱死亡?”
  1. 可达性分析出不可达之后,只是死缓,并不是一定不可逃脱。
  2. 两次标记:1,发现没有与引用链相连,第一次被标记,并进行删选(对象是否有必要执行finalize()方法,对象没有覆盖finalize()方法OR已经被JVM调用过,均视为没有必要执行)  2.有必要时,进入F-Queue队列,稍后被低优先级Finalize线程执行(触发finalize()方法)它。但是并不会承若等待其运行结束,否则一旦某个对象在finalize()中缓慢或死循环,将导致F-Queue其他对象永久等待,会导致GC内存回收系统崩溃。
  3. “逃脱死亡”:在finalize()中拯救自己【不推荐用,毕竟throws等那么多方法】,重新与引用链建立连接,在第二次标记时候会被移除“即将回收”集合,否则就被回收了。不够注意,任一个对象的finalize()方法.只能被调用一次。对象下次面临回收,无法在从相同的finalize()方法中逃脱。
方法区GC(eg:在HotSpot虚拟机的永久代)的垃圾回收性价比不高、效率相比堆中新生代(70-95%),但是主要有:
     废弃常量、无用的类
     对象
是不使用的时候就可以被回收。
    “废弃常量”判断常量是否废弃: “abc”字符串存在常量池中,但是系统没有对该字符串的引用,(没有任何String对象引用“abc”,也没有其他地方引用这个字面量,如果此时发生内存回收,那么这“abc”会被系统请出常量池。) 常量池中其他类(接口)、方法、字段的符号引用与此类似。
     “无用的类”判断稍微苛刻《判断条件》
           1.类的所有势力都已被回收,Java堆中不存在该类的任何实例。
          2.类对应的java.lang.Class 对象没有被引用,拒绝一切可能的反射访问到该类的方法。
          3.该类的 ClassLoader已经被回收。
垃圾回收算法:
  1. Mark-Sweeping 最基础-效率不高、空间不连续会有大量内存碎片,无法找到足够的连续内存不得不触发一次GC
  2. Coping -安容量均分为两块A,B,只用一块A,用完了A将还存活的复制到另一块B,清除A.但可用内存会变小。由于很多“朝生夕死”所以设置Eden:Survivor=8:1:1,新生代可用容量会提高到90%。但如果Survivor内存不足以承载那边copying过来的话,就要借助老年代进行担保分配。
  3. Mark-Compact:标记-整理:类似MarkSweeping,但后续不是标记就直接清除,而是让所有存活对象都向一端移动,直接清除边界外内存。避免了大量的资源碎片。
  4. Generational Collection:分代收集:根据存活周期不同分成老年代、新生代,新生代多用Copying;老年代多用1.3标记-**方法。
   垃圾回收器:7种,分别在新生代、老年代。有连线,即可以搭配使用(多是新生代+老年代各一款)。重点分析CMS、GI两款相对复杂的收集器。
     新生代:copying算法的天下
  1. Serial : 单线程-JVM在client模式下默认的新生代收集方式,相比其他的单线程简单高效,因为专心所以高效。在GC时,必须暂停其他所有工作线程,直到其GC结束。用户未知情况下线程就被停了,尴尬!用户线程停顿时间可能久哦,一般控制在几十ms-100ms不频繁的话还是可以被client JVM接受的。【妈妈打扫房间时,我只能出去等着】
  2. ParNew :Serial的多线程版本【妈妈打扫房间,我可以边扔纸屑】,除了多线程,甚至Serial的所有控制参数、回收算法、策略等是一样。只有Serial和ParNew能和CMS搭档呢。单线程工作环境下不会优于1.serial(专业),因为线程交互等开销。默认的开始的收集多线程数,于CPU数量一样。
  3. Parallel Scavenge : 特点:目标是达到可控的吞吐量(=运行用户代码时间A/(A+垃圾回收时间))。其他eg CMS:减少停顿时间;而这个吞吐率则可以高效利用CPU时间。设置参数:GC停顿时间、直接设置吞吐量。
     老年代:
  1. Serial Old:Serial 的老年代版本。只不过是用Mark-Sweeping算法。给Client模式下的JVM使用。
  2. Parallel Old:Parallel Scavenge的老年版本,多线程+Mark-compact算法。一对一,新生代选那个,老年代必须选这个。
  3. CMS(Concurrent Mark Sweep): 并发收集+低停顿。目的:获取最短停顿时间。常见于:网站  or B/S(Browser/Server)系统的服务端上。他们的特点是:重视系统停顿时间,以为用户提供最好的体验。<4步骤> 
    初始标记(标记GCRoots能关联到的对象,最短)---并发标记(GC Roots Tracing过程,时间最最长)---重新标记(修正并发标记过程program运行导致的一些变动,稍长)---并发清除(最最长)  最最长的2个阶段,回收线程可与用户线程同时工作->可认为CMS回收内存过程与用户线程并发进行的。
    对CPU很敏感(面向并发的特性决定了);CMS无法处理浮动垃圾(并发清理时运行的程序生成的新垃圾,当次GC无法清理,只能留给下次),可能“Concurrent Mode Failure”失败导致另一次FullGC;基于M-S算法,回收会有大量碎片,找不到足够连续内存又会触发Full-GC。
  4. G1(Garbage-First)最前沿,面向服务端的---并行与并发+分代收集+空间整合+可预测的停顿。                                                                      初始标记---并发标记---最终标记---筛选回收

如何能看懂GC日志&常见的垃圾收集器参数

  


阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页