读书笔记《深入理解Java虚拟机》: 垃圾收集器与内存分配策略 | idouba

读书笔记《深入理解Java虚拟机》: 垃圾收集器与内存分配策略

  1. 当需要排查各种内存溢出、内存泄露问题时,或者发现gc成为并发瓶颈时,需要对哪些号称“自动化”的内存分配与回收技术进行监控和调节
  2. 程序计算器、虚拟机栈、本地方法栈3个区域随现场而生存、灭亡;栈中的栈帧随着方法的进入和退出而有条不紊的执行出栈和入栈操作,每个栈帧分配多说内存基本上在类结构确定下来时就是已知,这几个区域内存分配和回收是确定的。
  3. 主流的java虚拟机不采用引用计数算法,最主要原因是很难结局对象之间的相互循环引用问题。
  4. 可达性分析算法的基本原理是通过一系列称为GC roots的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链reference? chain,当一个对象到GC roots没有任何引用链路时。证明该对象是不可用的。
  5. GC? roots包括如下几种:
  • 虚拟机栈(栈帧中的本地变量表)中引用的对象
  • 方法区中类静态属性引用的对象
  • 方法区中常量引用的对象
  • 备份方法栈中JNI引用的对象
  1. 为一个对象设置虚引用的唯一目的就是能在这个对象被收集时收到一个系统通知。
  2. 任何一个对象的finalize()方法只会被系统自动调用一次,如果对象面临下一次回收,它的finalize()方法不会别再次执行。
  3. 当对象定义了finalize()方法,则在该对象不可达时,该对象会被放置到一个叫F-Queue的队列中,并在稍后由虚拟机的一个低优先级的Finalizer现场执行。Finalize()不是析构,可以被try-finally或者其他方式替代,推荐不要使用。
  4. 永久代懒觉收集主要回收两部分:废弃常量和无用的类。
  5. 类需要满足3个条件会被认为“无用”
  • 类的所有实例被回收,即java堆中不存在该类的任何实例
  • 加载该类的ClasssLoader已经被回收。
  • 该类对应的java.lang.Class对象没有在任何地方呗引用,无法再任何地方通过放射访问到该类的方法。?
  1. 标记-清除算法的不足是,1.效率,2,生成大量不连续的内存碎片
  2. 分代收集算法。在新生代每次垃圾收集都发现当了的大量的对象死去,只有少量的存活,采用复制算法,只是复制少量存辉对象成本较低;而老年代中因为对象存活率搞,没有额外空间进行分配担保,必须使用“标记-清理”或“标记-整理”算法进行回收
  3. 可达性分析对执行时间的敏感体现在哎GC停顿上,因为这项分析工作必须在一个能确保一致性的快照中进行,即分析期间整个执行期限就像冻结在某个时间点上,不会出现分析过程中对象的应用关系还在不断地发生变化。这点事导致GC进行时必须停顿所以java执行线程(即stop the world)的重要原因。即使号称几乎不发生停顿的CMS收集器中,枚举根节点时也必须停顿。
  4. 垃圾收集器是内存回收的具体实现。Java虚拟机规范对懒觉收集器应该如何实现并没有任何规定,因此不同厂商、不同版本的虚拟机的收集器可能会有很大差别。
  5. Serial收集机器。进行懒觉收集时,必须安亭其他所以工作现场。是虚拟机运行在Clieent模式下的默认新生代收集器,因为其简单而高效。尤其对于大哥CPU的环境。
  6. ParNew收集器。ParNew收集器是Serial收集器的多线程版本,除了使用多条线程进行垃圾收集外,其余行为包括所有控制参数、收集算法、Stop the world、对象分配规则、回收测量都与Serial收集器完全一致。是许多运行在Server模式下的虚拟机首选的新生代收集器。除了serial外,只有ParNew 可以和CMS配合。使用-XX:+UseConcMarkSweepGC选项后默认的新生代收集器就是ParNew。
  7. Parallel Scavenge 收集器。一个新生代收集器,麻痹上达到一个可控的吞吐量throughput。吞吐量=运行用户代码时间/(运行用户代码时间+垃圾回收时间) Parallel Scanvenge 收集器也成为“吞吐量优先”收集器。他有一个参数-XX:UseAdaptiveSizePolicy这样一个开关参数,打开后,不需要手动置顶新生代大小(-Xmn)、Eden与Survivor的比例(-XX:SurvivorRadio)、晋升到老年代的对象年龄(-XX:PretenureSizeThreshold)等细节参数,虚拟机会根据当前系统运行情况收集性能监控参数,动态调整这些参数以达到最大的吞吐量。
  8. Serial? Old收集器。是Serial收集器的老年代版本。同样是单线程收集器,使用“标记-整理”算法。Client模式下使用。
  9. Parallel Old收集器,是Parallel Scavenge收集器的老年的版本,使用多线程和“标记-整理”算法。在注重吞吐量并且CPU资源敏感的场合,都有限考虑Parallel Scanvenge 加Prallel Old收集器。
  10. CMS收集器,Concurrent? Mark Sweep收集器是一种以获取最短收集停顿时间为目标的收集机器。CMS收集器基于“标记-清除”算法。整个过程包括:
  • 初始标记 CMS initial mark
  • 并发标记 CMS concurrent mark
  • 重新标记? CMS remark
  • 并发清除 CMS concurrent sweep

初始标记、重新标记两个步骤仍然需要Stop the world 。初始标记经济标记下GCroots能直接关联到的对象,速度快。并发标记就是经GC roots tracing的过程,重新标记阶段则是为了修正并发标记期间因为用户程序极限运行而导致标记产生宾东的那一部分对象的标记记录。这个阶段停顿时间比初始标记稍微长,但是比并发标记短的多。

  1. 要是CMS运行期间预留的内存无法满足程序需要,就会出现一处Concurrent mode failure失败,这时虚拟机会启动后备预案:力所能及启动Serial Old收集器来重新进行老年代的收集,这时停顿时间就很长了。
  2. G1收集器是面向服务端的收集器,目标是替换CMS。

原创文章。为了维护文章的版本一致、最新、可追溯,转载请注明: 转载自idouba

本文链接地址: 读书笔记《深入理解Java虚拟机》: 垃圾收集器与内存分配策略


, ,

No comments yet.

发表评论