引用计数器算法GC存在的问题是?html
描述:引用计数器法给对象中添加一个引用计数器,没当一个地方引用它,计数器就加一,引用失效时减一,任何引用计数器为0的对象就是不可能再被使用的对象。java
引用计数器算法的效率也比较高,主流的JVM里面并无选用引用计数器来管理内存,其中最主要的问题是不能解决对象之间循环引用的问题。算法
java是经过可达性分析来判断对象是否存活,这个算法的基本思路是经过一系列的称为“GC Roots”的对象为起始点,从这些节点向下搜索,搜索全部的路径称为引用链;引用链不能到达的对象节点是GC须要回收的。缓存
在java语言中可被称为“GC Roots”的对象包括下面几个方面:bash
不管是引用计数器仍是可达性分析判断的标准都是对象是否引用。jvm
在jdk1.2后,java对引用进行了扩充,将引用分为强引用 、软引用、弱引用、虚引用4种,强弱依次递减。性能
public class Main {
public static void main(String[] args) {
new Main().fun1();
}
public void fun1() {
Object object = new Object();
Object[] objArr = new Object[1000];
}
}
复制代码
import java.lang.ref.SoftReference;
public class Main {
public static void main(String[] args) {
SoftReference<String> sr = new SoftReference<String>(new String("hello"));
System.out.println(sr.get());
}
}
复制代码
public class Main {
public static void main(String[] args) {
WeakReference<String> sr = new WeakReference<String>(new String("hello"));
System.out.println(sr.get());
System.gc(); //通知JVM的gc进行垃圾回收
System.out.println(sr.get());
}
}
复制代码
ReferenceQueue<String> queue = new ReferenceQueue<String>();
PhantomReference<String> pr = new PhantomReference<String>(new String("hello"), queue);
System.out.println(pr.get());
复制代码
如何利用软引用和弱引用解决OOM问题优化
前面讲了关于软引用和弱引用相关的基础知识,那么到底如何利用它们来优化程序性能,从而避免OOM的问题呢?spa
下面举个例子,假若有一个应用须要读取大量的本地图片,若是每次读取图片都从硬盘读取,则会严重影响性能,可是若是所有加载到内存当中,又有可能形成内存溢出,此时使用软引用能够解决这个问题。线程
设计思路是:用一个HashMap来保存图片的路径 和 相应图片对象关联的软引用之间的映射关系,在内存不足时,JVM会自动回收这些缓存图片对象所占用的空间,从而有效地避免了OOM的问题。在Android开发中对于大量图片下载会常常用到。
要宣告一个对象死亡,至少经历两次标记过程:若是进行可达性分析时没有到达的引用链,将会作第一次标记,此处须要进行一次筛选,条件是有必要执行finalize()方法,当对象没有覆盖finalize(),或者已经被jvm调用,这两种状况称为“没有必要执行”;若是对象被判断有必要执行,会被放置在一个F-Queue队列,稍后有优先级低的线程进行第二次标记,若是对象finalize从新进行了引用,那么将会移出回收队列,不然会被进行垃圾回收。
判断一个类须要回收的条件:
参考书籍: 深刻理解jvm
引用博客: https://www.cnblogs.com/dolphin0520/p/3784171.html