福州做网站企业,用dw6做网站,用windows搭建手机网站,电子商务网站建设完整案例教程s2sh pdf下载百日筑基第三十四天-JAVA中的强/软/弱/虚引用
Java对象的引用被划分为4种级别#xff0c;分别为强引用、软引用、弱引用以及虚引用。帮助程序更加灵活地控制对象的生命周期和JVM进行垃圾回收。
强引用
强引用是最普遍的引用#xff0c;一般把一个对象赋给一个引用变量分别为强引用、软引用、弱引用以及虚引用。帮助程序更加灵活地控制对象的生命周期和JVM进行垃圾回收。
强引用
强引用是最普遍的引用一般把一个对象赋给一个引用变量这个引用变量就是强引用。这个引用保存在Java栈中而真正的引用内容保存在Java堆中。
// 强引用
Object objnew Object();如果使用了强引用垃圾回收器GC时不会回收该对象**当空间不足时JVM宁愿抛出OutOfMemoryError异常。**因为JVM认为强引用的对象是用户正在使用的对象它无法分辨出到底该回收哪个强行回收有可能导致系统严重错误。如果想GC时回收该对象让其超出对象的生命周期范围或者设置引用指向null并且会执行对象的finalize 函数。如下帮助垃圾回收期回收此对象具体什么时候收集这要取决于GC算法。
obj null;举个例子 StrongRefenenceDemo中尽管o1已经被回收但是o2强引用 o1一直存在所以不会被GC回收。
public class StrongRefenenceDemo {public static void main(String[] args) {Object o1 new Object();Object o2 o1;o1 null;System.gc(); // 其实就算我们显示调用GC 也可能不会立即执行System.out.println(o1); //nullSystem.out.println(o2); //java.lang.Object4534fdg7}
}软引用
对象处在有用但非必须的状态只有当内存空间不足时GC会回收该引用对象的内存。可以用来实现高速缓存比如网页缓存、图片缓存等。需要通过SoftReference类来实现。
// 注意sr引用也是强引用它是指向SoftReference这个对象的
// 这里的软引用指的是指向new String(str)的引用也就是SoftReference类中T
SoftReferenceString sr new SoftReferenceString(new String(str));软引用可以和一个引用队列ReferenceQueue联合使用,如果软引用所引用对象被垃圾回收Java虚拟机就会把这个软引用加入到与之关联的引用队列中。
ReferenceQueueObject queue new ReferenceQueue();
Object obj new Object();
SoftReference softRef new SoftReferenceObject(obj,queue);//删除强引用
obj null;//调用gc
System.gc();
System.out.println(gc之后的值: softRef.get()); // 对象依然存在
//申请较大内存使内存空间使用率达到阈值强迫gc
byte[] bytes new byte[100 * 1024 * 1024];//如果obj被回收则软引用会进入引用队列
Reference? reference queue.remove();
if (reference ! null){System.out.println(对象已被回收: reference.get()); // 案例一 SpringBoot源码中大量使用ConcurrentReferenceHashMap合理的使用内存间接的优化JVM提高垃圾回收效率。
public class ConcurrentReferenceHashMapK, V extends AbstractMapK, V implements ConcurrentMapK, V {private static final ConcurrentReferenceHashMap.ReferenceType DEFAULT_REFERENCE_TYPE;static {DEFAULT_REFERENCE_TYPE ConcurrentReferenceHashMap.ReferenceType.SOFT;}......
}SpringFactoriesLoad源码Springboot SPI机制的主角
public final class SpringFactoriesLoader {private static final MapClassLoader, MultiValueMapString, String cache new ConcurrentReferenceHashMap();......private static MapString, ListString loadSpringFactories(Nullable ClassLoader classLoader) {MultiValueMapString, String result (MultiValueMap)cache.get(classLoader);if (result ! null) {return result;} else {try {EnumerationURL urls classLoader ! null ? classLoader.getResources(META-INF/spring.factories) : ClassLoader.getSystemResources(META-INF/spring.factories);LinkedMultiValueMap result new LinkedMultiValueMap();while(urls.hasMoreElements()) {......}cache.put(classLoader, result);return result;} catch (IOException var13) {throw new IllegalArgumentException(Unable to load factories from location [META-INF/spring.factories], var13);}}}AnnotationsScanner自动配置过程中的注解扫描
abstract class AnnotationsScanner {private static final MapAnnotatedElement, Annotation[] declaredAnnotationCache new ConcurrentReferenceHashMap(256);private static final MapClass?, Method[] baseTypeMethodsCache new ConcurrentReferenceHashMap(256);ThreadPoolTaskExecutor 异步任务线程池
public class ThreadPoolTaskExecutor extends ExecutorConfigurationSupport implements AsyncListenableTaskExecutor, SchedulingTaskExecutor {public ThreadPoolTaskExecutor() {this.decoratedTaskMap new ConcurrentReferenceHashMap(16, ReferenceType.WEAK);}案例二 Mybatis缓存类SoftCache用到的软引用
public Object getObject(Object key) {Object result null;SoftReferenceObject softReference (SoftReference)this.delegate.getObject(key);if (softReference ! null) {result softReference.get();if (result null) {this.delegate.removeObject(key);} else {synchronized(this.hardLinksToAvoidGarbageCollection) {this.hardLinksToAvoidGarbageCollection.addFirst(result);if (this.hardLinksToAvoidGarbageCollection.size() this.numberOfHardLinks) {this.hardLinksToAvoidGarbageCollection.removeLast();}}}}return result;}弱引用
弱引用就是只要JVM垃圾回收器发现了它不管内存是否足够,都会被回收。
Object object new Object();
WeakReferenceObject weakReference new WeakReference(object);
Object result weakReference.get();案例: WeakHashMap当key只有弱引用时GC发现后会自动清理键和值作为简单的缓存表解决方案。
public class WeakHashMapDemo {public static void main(String[] args) throws InterruptedException {myHashMap();myWeakHashMap();}public static void myHashMap() {HashMapString, String map new HashMapString, String();String key new String(k1);String value v1;map.put(key, value);System.out.println(map);key null;System.gc();System.out.println(map);}public static void myWeakHashMap() throws InterruptedException {WeakHashMapString, String map new WeakHashMapString, String();String key new String(weak);String value map;map.put(key, value);System.out.println(map);//去掉强引用key null;System.gc();Thread.sleep(1000);System.out.println(map);}
}ThreadLocal ThreadLocal.ThreadLocalMap.Entry继承了弱引用key为当前线程实例和WeakHashMap基本相同。
static class ThreadLocalMap {static class Entry extends WeakReferenceThreadLocal? {Object value;Entry(ThreadLocal? k, Object v) {super(k);value v;}}//......}虚引用
虚引用和没有引用是一样的需要和队列ReferenceQueue联合使用。**当jvm扫描到虚引用的对象时会先将此对象放入关联的队列中因此我们可以通过判断队列中是否存这个对象来进行回收前的一些处理。**有哨兵的作用。
Object object new Object();
ReferenceQueue queue new ReferenceQueue();
PhantomReference pr new PhantomReference(object, queue);