【Java】深入理解JVM学习笔记(三) —— GC收集器和内存分配

判断对象是否存活

引用计数算法

很多判断对象是否存活的方式就是引用计数算法:给对象添加一个引用计数器,每当一个地方引用它,计数器+1;引用失效,计数器-1。


任何时刻计数器为0的对象是不可能再被使用的。


Java虚拟机没有使用主流的引用计数法管理内存。主要原因是难以解决对象之间相互循环引用的问题

classA.instance = classB
classB.instance = classA

classA和classB已经不可能再被访问,但是classA和classB互相引用对方,导致计数器永远不可能是0,导致GC无法回收两个对象


可达性分析算法

通过一系列称为”GC Roots”对象作为起始点,从这些节点向下搜索,搜索过的路径称为引用链。


当一个对象的GCRoots没有任何引用链相连时,则证明该对象不可用。

在java中可作为GCRoots对象的是

  1. 虚拟机栈(栈帧本地变量表)引用的对象
  2. 方法区中类属性引用对象
  3. 方法区中常量引用对象
  4. 本地方法栈(JNI)中引用对象

引用

Java引用分类(又上到下引用关系依次减弱)

  • 强引用
    • 必须存在的对象
    • 类似ObjectA objA = new ObjectA()
  • 软引用
    • 有用但非必须的对象
    • 在发生内存溢出后,可进行二次回收
  • 弱引用
    • 非必须对象
    • 无论当前内存是否足够,都会回收掉只被弱关联对象
  • 虚引用
    • 是否存在不会对生存时间对其影响

生存或者死亡

判断一个对象死亡,至少经历两次标志过程:如果对象进行可达性分析,GCRoot没有相连的引用链,那么被第一次标记进行筛选筛选的条件是是否有必要进行finalize()方法;对象没有覆盖finalize()方法或者已经被虚拟机调用过finalize()方法,则该对象没必要销毁;如果这个对象有必要执行finalize()方法,会将它放置在F-Queue队列中,并在稍后由一个虚拟机自动执行、低优先级的Finalizer线程去执行;GC稍后会对F-Queue中的对象进行二次标记


如果对象需要拯救自己不被回收。只要重新与引用链的任何一个对象重新关联为止(例如.this)


注意:自救的机会只能使用一次;一个对象的finalize方法最多只被系统调用一次

private static FinallyProperty escapeGC = null;

@Override
void finalize() throws Throwable{
   super.finalize();
   FinallyProperty.escapeGC = this;   
}

回收方法区

永久代的垃圾回收主要是2个部分:废弃变量和无用的类

  • 废弃变量:与Java堆中的回收类似;例如.没有任何一个地方引用常量池的”abc”字面量,这时发生了内存回收;这个”abc”会被清理出常量池
  • 无用的类需要满足的3个条件
    • java堆中不存在该类的任何实例
    • 加载该类的ClassLoader已被回收
    • 无法在任何地方通过反射访问该类的方法

垃圾收集算法

标记-清除

在回收之前,首先标志出需要回收的对象,在标志完成后统一回收所有标志对象
后面的算法都是基于”标记-清除”算法的改进

该算法的主要缺点
1. 效率低下:产生过多内存碎片
2. 空间占用过多

复制算法

解决”标记-清除”算法效率问题


将内存划分为容量相等的2个部分,每次只使用其中一块。当这块内存使用完毕,将还存活的对象复制在另一块上面。然后把已使用的空间一次性清理掉。


每次对整个半区进行回收,而不讨论内存碎片等复杂情况,只需移动堆顶指针、按顺序分配内存即可。

标志-整理算法

复制收集算法在对象存活率过高时进行复制操作,影响效率。


根据老年代特点,提出了标志-整理算法;标志过程和标志-清除的过程一样。整理:让所有存活对象向一端移动,然后直接清理掉边界以外的内存

分代收集算法

一般把Java划分成新生代和老年代;根据各个年代的特点采用合适的收集算法
通常新生代采取:复制算法
老年代采取:标志-整理或者标志-清除算法

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值