JVM模型-垃圾收集策略与算法

程序计数器、虚拟机栈、本地方法栈随着线程而生,也随着线程而灭;栈帧随着方法的开始而入栈,随着方法的结束就出栈。这几个区域的内存分配和回收都有着确定性。
而对于Java堆和方法区,我们只有运行的时候知道会创建哪个内存,这个内存的创建和回收都是动态的,垃圾收集器所关注正是这部分内存。

判定对象是否存过

如果一个对象不被任何对象或者变量引用,那么它就是无效的对象,需要被回收。

引用计数器法

在对象头上维护一个counter计数器,被对象引用则计数器+1,若引用失效则计数器-1。当计数器为0的时候就认为该对象无效了。但是如果出现了循环引用的情况,循环的对象的计数器不可能为0。

可达性分析

所有的GC Roots直接或者间接关联有效对象的,和GC Roots 没有关联的对象被回收
CG Roots 指的是

  • java虚拟机栈中引用的对象
  • 本地方法栈中引用的对象
  • 方法区中常量引用对象
  • 方法区中类静态属性引用的对象
    CG Roots 不包括堆中对象所引用的对象,这样就不会出现循环问题

引用的种类

强引用

类似“Object a = new Object()” 这类的引用,就是强引用,只要存在强引用,垃圾回收期就不会回收强引用,如果错误的给了强应用,对象就会存在很长一段时间内不会被回收,会产生内存泄露

软引用

软引用通常是来实现内存敏感的缓存,当jvm认为内存不足的时候吗,才会试图回收软引用所指向的对象

弱引用

弱引用的强度比软引用更弱一些,当jvm进行垃圾回收时,无论内存是否充足,都会回收被弱引用关联的对象

虚引用

一个对象是否有虚引用的存在,完全不会对其生存时间构成影响,它仅仅是提供了一种确保对象被finalize之后,做某些事情的机制。

回收堆中的无用内存

对于可达性分析不可达的内存,也并不是没有存活的可能。需要判断对象的finalize()是否被执行过,如果没有执行,就会被jvm放到一个队列中执行,如果出现了耗时操作,则直接清除对象。如果执行成功,讲this赋给某一个引用,那么改对象就重生了,如果没有,那么就会被垃圾收集器清除

回收方法区内存

方法区中存放生命周期比较长的类信息、常量、静态变量每次垃圾收集只有少量的垃圾被清除。方法区中主要清除两种垃圾:

  • 无用的类
  • 废弃常量

判定废弃常量

只要常量池中的常量不被任何变量或者对象引用,那么这些常量就会被清除掉

判定无用类

判定一个类是否是无用类,条件比较苛刻

  • 该类的所有对象都已经被清除
  • 加载该类的ClassLoader已经被回收
  • 该类的 java.lang.Class对象没有在任何地方被引用,无法通过反射来访问该类的方法

垃圾收集算法

标记-清除算法

遍历所有的GC Roots,然后将所有的GC Roots对象标记为活对象。
清除过程中将遍历堆中的所有对象,将没有被标记的对象被清除掉。与此同时,清除那些被标记过的对象的标记,以便下次垃圾回收
这种方法有两个不足的地方

  • 效率问题: 标记和清除两个过程的效率都不高
  • 空间问题:标记清除之后会出现大量的空间碎片,碎片太多可能导致以后分配较大的对象,无法找到足够的连续内存,而不得不提前触发下一次垃圾回收操作

复制算法(新生代)

为了解决效率问题,将可用内存按照容量分为大小相等的两份,每次只用其中一份,当这块内存用完,需要进行垃圾收集时,就将活着的对象复制到另外一块上面,然后将第一块内存全部清掉。

  • 优点:不会有内存碎片
  • 缺点:内存缩小为原来的一半,浪费空间

为了解决空间问题,可以将内存分为三个部分:Eden、FromSurvivor、ToSurvivor,比例是8:1:1,每次使用Eden和其中一块内存,回收时,讲Eden和Survivor中活着的对象的那部分一起复制到另外一个Survivor中,最后清理带哦Eden和Survivor的空间。这两只有十分之一的内存被浪费,但是如果如果活着的内存大于10%的内存空间,就需要其他内存用来担保分配

标记-整理算法(老年代)

  • 标记:同标记清除算
  • 整理:移动所有存活的对象,按照内存地址次序排序,然后将内存地址末端以后的内存全部回收
    这是一种老年代的算法,老年代相对比较大,如果复制就会有效率影响

分代收集算法

  • 新生代 复制算法
  • 老年代 标记清除算法
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值