带着问题去学习,会事半功倍。
- 哪些内存需要回收?
- 何时回收?
- 如何回收?
前提
程序计数器、虚拟机栈、本地方法栈随线程生而生,灭而灭,栈中栈帧随方法进入和退出而执行出栈入栈操作,每个栈帧分配内存基本可定, 所以如何回收不需要过多考虑,方法结束,内存自然回收。
堆和方法区就不一样了:一个方法只有在运行时才知道需要创建多少个实例对象,其内存分配和回收是动态的。
so,我们平时说的GC(Garbage Collection),主要指对这两个区域。
如何判断对象是否已“死”
- 引用计数法
对象引入一个计数器,有地方引入时+1,失效时-1。但因jvm对象相互循环引用问题,并没有采用此算法。 - 可达性分析
基于Gc Roots集合向下搜索,根据搜索路径(引用链)来判断对象是否可达。
Gc Roots是这样一群集合:1) 栈中Native方法引用的对象;2) 基本数据类型对应的Class对象,异常对象如OOMError,系统类加载器等;3) 被同步锁(synchronized)持有的对象 - 总结 :
无论引用计数还是是否可达都和“引用”有关。且一个对象不仅仅只有“被应用”和“未被引用”两种状态,我们想描述一个对象内存够用时,保留之,内存紧张时,抛弃之,这是就涉及到了引用强度的概念,依次为:
1)强引用:new关键字修饰,不会回收;
2)软引用:还有用,非必须。列入回收范围进行第二次回收;
3)弱引用:非必须,下次GC会被回收;
4)虚引用:其存在目的只是此对象被GC时收到系统通知。
关于finalize()对象救赎,不建议使用该方法,因被救赎后是把对象放在一个F-Queue队列里,且由jvm优先级很低的线程去执行,不确定是否执行,官方已明确不建议使用。
垃圾收集算法
如何判断对象是否消亡角度上,垃圾收集算法可划分为“引用计数式收集”(jvm不涉及)和“追踪式收集”,即直接垃圾收集和间接收集。其中追踪式收集主要算法包括:
- 分代收集理论:部分收集(Partial GC)
新生代收集(MinorGC/Young GC)
老年代收集(Major GC/old GC)
混合收集(Mixed GC),如G1收集器 - 标记-清除算法
- 标记-复制算法
- 标记-整理算法
经典垃圾收集器
- G1
- Serial收集器
- ParNew收集器
- CMS收集器
- …… (还有很多)总结一下:衡量收集器重要指标:内存占用、吞吐量、延迟
总结
垃圾收集器有很多种,涉及大量可调节参数,只有根据实际应用需求选择最优的收集方式获得最好的性能。
没有固定收集器、参数组合,也没有最优调优方法。
(下一章会总结内存分析工具和调优案例)
本文详细探讨了Java垃圾回收的基本原理,包括不同类型的引用、如何判断对象是否存活以及各种垃圾收集算法。此外还介绍了常见的垃圾收集器及其工作原理。
576

被折叠的 条评论
为什么被折叠?



