美文网首页
垃圾回收器GC

垃圾回收器GC

作者: Herman7z | 来源:发表于2018-03-22 14:36 被阅读0次

内存溢出:无法为对象分配到内存
内存泄漏:代码问题,一些无用的对象无法被GC回收(数据库连接)

如何判断对象是否已经可以被回收

引用计数算法:给每个对象添加一个引用计数器,没当有一个地方引用就+1,当一个地方引用失效就-1,直到计数器为0,对象就可以回收。在JVM中没有采用这种算法,无法解决对象的循环引用

可达性分析算法:使用图论的思想实现,进入入口程序后就会建立一条引用链,不管多少对象,只要脱离了主链,那么对象就是可以被回收的。

要真正回收一个对象要经历两个标记过程:

  1. 当确定一个对象没有任何引用链可以到达,第一次标记
  2. 若对象实现了finalize方法,并且在方法中将自己的引用赋值到了一个变量,那么将对象移除“即将回收”的集合
    注意:finalize方法不推荐使用,实现了finalize的对象都会放入到这个队列中去执行,JVM创建一个低优先级的线程去执行,运行代价高,不确定性大,无法保证对象调用的顺序;使用try-finally完全可以代替
在Java中引用分为4中类型:

强引用:Object obj = new Object()
软引用:在系统将要发生内存溢出的时候回收,若回收后内存还是不足够,那么抛出内存溢出异常 ( SoftReference ) ,这种特点很适合做一些缓存
弱引用:关联的对象只能生存到下次垃圾回收器发生之前 ( WeakReference )
虚引用:只为了在对象被回收的时候获取一个系统通知 ( PhantomReference ) 只要一创建完就直接给回收了

垃圾收集算法

标记-清除:标记出哪些对象可以回收,清除掉可以回收的对象。缺点:标记和清除的过程效率都比较低;造成很多不连续的内存片段,若一旦出现了分配大的对象,就会再次触发垃圾回收,影响效率,若回收后还是不分配不到大的内存,会出现异常
标记-整理:标记出拿些对象可以回收,把存活的对象依次往前移动,使内存连续使用,清除掉末尾的所有可以回收对象
复制算法:把可用内存平分成两块,每次只是使用其中一块,在需要回收垃圾时检查出所有存活的对象复制到另一块内存中,清除使用的过那一块所有内存。效率高,但是浪费了一半的内存
分代收集算法:Java堆被分为了新生代和老年代;新生代中的对象存活时间短,采用复制算法;老年代的对象存活时间长,采用标记-整理或者标记-清除

内存分配

大多数情况下,对象在新生代分配内存;
大对象直接进入老年代。大对象对于虚拟机来说就是一个坏消息,更糟糕的是遇到一群朝生夕死的短命大对象,写程序时应当注意
长期存活的对象将直接进入老年代,在新生代中,每个对象都有一个年龄计数器,默认超过15岁的对象将会进入到老年代,在每进行一次Minor GC对于仍然存活的对象年龄加1。新生代中采用的复制算法,避免长期对象反复的复制

相关文章

网友评论

      本文标题:垃圾回收器GC

      本文链接:https://www.haomeiwen.com/subject/qbeaqftx.html