jvm堆中对象存活算法,内存泄漏,垃圾回收算法

版权声明:转载请注明出处 https://blog.csdn.net/h2604396739/article/details/87366329

首先说面:下面所有内容都是针对jvm 中堆区域。堆里面对象的回收jvm自动帮我们实现的,但是我们也需要了解其原理。

jvm堆中对象存活算法及其优缺点

1 引用计数算法
给对象增加引用计数器,每当有一个地方引用它时,计数器值加1;引用失效时,计数器值减1。当计数器的值为0时,代表可以回收了。但是很难解决对象之间的相互循环引用.
2 可达性分析算法
以一些称为”GC ROOTS”的节点作为起点,从这些节点开始向下搜索,所走过的路径称为引用链,当一个对象到GC ROOTS没有任何引用链相连时,说明对象是不可用的.
Java中可以作为GC ROOTS 的对象:

  • 虚拟机栈中引用的对象,
  • 本地方法栈中Native方法引用的对象
  • 方法区中类静态属性引用的对象,
  • 方法区中常量引用的对象.

注意:即便是不可达时,也不一定就会被回收,将会第一次被标记并被筛选,看是否有必要执行finalize()方法,如果finalize()方法没有被重写,并且finalize方法已经被调用则不再调用fianlize()方法;否则执行finalize方法,将对象放入F-quene队列,会再次进行标记,如果仍然没有GC ROOTS指向该对象,则清除.

内存泄漏

内存泄漏出现的根本原因:长生命周期的对象应用短生命周期的对象,导致短生命周期的对象无法释放内存
例如:
静态集合中的对象
集合中的对象先修改后移除,但实际并没有被移除
监听器,一个控件的诸如addXXXListener()等方法来增加监听器,但往往在释放对象的时候却没有记住去删除这些监听器,从而增加了内存泄漏的机会。
比如数据库连接(dataSourse.getConnection()),网络连接(socket)和io连接,除非其显式的调用了其close()方法将其连接关闭,否则是不会自动被GC 回收的。

jvm堆的垃圾回收算法及其优缺点

1 标记-清除算法
首先标记所有需要被回收的对象,然后在标记完成后统一回收所有被标记的对象.两点不足:
A标记和清除的效率都很低 b清除后会产生大量不连续的空间碎片

2 标记整理算法
结合了标记清理和复制算法,让存活的对象提前移向一端连续的空间然后直接清理剩余的部分.优点:无空间碎片,清理迅速 缺点:仍然需要移动
3 复制算法
把内存空间分为两部分(8:1),每次仅仅使用8的部分,清理时将存活的对象放到另外一个1的部分,然后一次清理所有的8的部分.
优点:清除迅速,不会产生不连续的空间碎片,但是需要复制并且可用的空间因为要预留所以减少.,且可能出现预留50%(所有对象都存活)的情况,此时就比较麻烦,可用空间仅有一半.
4分代收集算法
根据对象存活周期不同,将其分为新生代和老生代,因为新生代会出现很多朝生夕死的对象,所以针对新生代空间块使用复制算法,而对老生代使用标记清除或标记整理算法.

猜你喜欢

转载自blog.csdn.net/h2604396739/article/details/87366329