zoukankan      html  css  js  c++  java
  • jvm 07-java引用类型

    java引用类型

    • 强引用:当内存不足的时候,都不会进行空间回收,最终JVM抛出OutOfMemoryError
    • 软引用:当内存不足的时候,进行对象的回收处理,往往用于高速缓存中
    • 弱引用:不管内存是否紧张,只要GC运行都会回收
    • 幽灵引用:和没引用一样。

    强引用

    • JVM默认支持模式
    • 在引用期间内,如果该堆内存被指定的栈内存有联系,那该对象就无法被GC所回收
    • 一旦出现内存不足,就会出现OutOfMemoryError异常
    • 正因为强引用具备内存分配异常问题,因此尽量少实例化对象

    测试程序:

    package cn.liang.jvm;
    import static org.hamcrest.CoreMatchers.nullValue;
    import java.lang.ref.SoftReference;
    public class referenceType2 {
    	public static void main(String[] args) {
    		Object object = new Object();
    		Object ref = object;
    		object = null;
    		System.out.println("内存充足时进行gc回收:");
    		System.gc();
    		System.out.println(ref);
    		System.out.println("内存不足时进行gc回收:");
    		try {
    			String string = "liangjingfu";
    			while (true) {
    				string += string + string;
    				string.intern();	
    			}
    		} catch (Throwable e) {
    		}
    		System.out.println(ref);
    	}
    }
    

    输出结果:

    内存充足时进行gc回收:
    java.lang.Object@7852e922
    内存不足时进行gc回收:
    java.lang.Object@7852e922
    

    软引用

    • 在许多的开源组件中,往往会使用软引用作为缓存组件出现
    • 软引用不足时回收,不充足时不回收
    • 软引用需要一个单独的类来实现控制:java.lang.ref.SoftReference
      • 构造函数:public SoftReference(T referent)
      • 取出数据:public T get();

    测试程序:

    package cn.liang.jvm;
    import static org.hamcrest.CoreMatchers.nullValue;
    import java.lang.ref.SoftReference;
    public class referenceType2 {
    	public static void main(String[] args) {
    		Object object = new Object();
    		SoftReference<Object> ref = new SoftReference<Object>(object);
    		object = null;
    		System.out.println("内存充足时进行gc回收:");
    		System.gc();
    		System.out.println(ref.get());
    		System.out.println("内存不足时进行gc回收:");
    		try {
    			String string = "liangjingfu";
    			while (true) {
    				string += string + string;
    				string.intern();	
    			}
    		} catch (Throwable e) {
    		}
    		System.out.println(ref.get());
    	}
    }
    

    输出结果:

    内存充足时进行gc回收:
    java.lang.Object@7852e922
    内存不足时进行gc回收:
    null
    

    弱引用:

    • 只要一进行GC处理,那么所引用的对象将会立即回收
    • 弱引用需要使用Map接口的子类:java.util.WeakHashMap
    • java.lang.ref包中存在一个WeakReference子类

    测试程序1:

    package cn.liang.jvm;
    import java.util.Map;
    import java.util.WeakHashMap;
    public class referenceType3 {
    	public static void main(String[] args) {
    		String keyString = new String("name");
    		String valueString = new String("liang");
    		Map<String, String> map = new WeakHashMap<String, String>();
    		map.put(keyString, valueString);
    		keyString = null;
    		System.out.println("内存进行gc回收前:");
    		System.out.println(map);
    		System.out.println("内存进行gc回收后:");
    		System.gc();
    		System.out.println(map);
    	}
    }
    

    输出结果:

    内存进行gc回收前:
    {name=liang}
    内存进行gc回收后:
    {}
    

    测试程序2:

    package cn.liang.jvm;
    import java.lang.ref.WeakReference;
    import java.util.Map;
    import java.util.WeakHashMap;
    public class referenceType3 {
    	public static void main(String[] args) {
    		String keyString = new String("liang");
    		WeakReference<String> reference = new WeakReference<String>(keyString);
    		keyString = null;
    		System.out.println("内存进行gc回收前:");
    		System.out.println(reference.get());
    		System.gc();
    		System.out.println("内存进行gc回收后:");
    		System.out.println(reference.get());
    	}
    }
    

    输出结果:

    内存进行gc回收前:
    liang
    内存进行gc回收后:
    null
    

    引用队列

    • 主要是保存那些准备被回收的对象
    • 所有的对象的回收扫描都是从根对象开始的
    • 引用路径的设置即确定好哪些对象可以被回收后,设置相应的引用强度
    • 引用队列可避免非强引用对象所带来的内存引用问题,该对象被回收后会自动保存
    • 找到对象5有两个路径:
      • 对象1 --> 对象5(强 + 软)
      • 对象2 --> 对象5(强 + 弱)

    测试程序:

    package cn.liang.jvm;
    import java.lang.ref.ReferenceQueue;
    import java.lang.ref.WeakReference;
    import java.util.Map;
    import java.util.WeakHashMap;
    public class referenceType4 {
    
    	public static void main(String[] args) throws Exception {
    		Object obj = new Object();
    		ReferenceQueue<Object> queue = new ReferenceQueue<Object>();
    		WeakReference<Object> reference = new WeakReference<Object>(obj,queue);
    		System.out.println("内存进行gc回收前:");
    		System.out.println(queue.poll());
    		obj = null;
    		System.gc();
    		Thread.sleep(100);
    		System.out.println("内存进行gc回收后,对象保存:");
    		System.out.println(queue.poll());
    	}
    }
    

    输出结果:

    内存进行gc回收前:
    null
    内存进行gc回收后,对象保存:
    java.lang.ref.WeakReference@7852e922
    

    幽灵引用

    • 永远取不了的数据

    测试程序:

    package cn.liang.jvm;
    import java.lang.ref.PhantomReference;
    import java.lang.ref.ReferenceQueue;
    import java.lang.ref.WeakReference;
    import java.util.Map;
    import java.util.WeakHashMap;
    public class referenceType5 {
    	public static void main(String[] args) throws Exception {
    		Object obj = new Object();
    		ReferenceQueue<Object> queue = new ReferenceQueue<Object>();
    		PhantomReference<Object> reference = new PhantomReference<Object>(obj,queue);
    		System.gc();
    		System.out.println("对象读取:");
    		System.out.println(reference.get());
    		System.out.println("对象保存后读取:");
    		System.out.println(queue.poll());
    	}
    }
    

    输出结果:

    对象读取:
    null
    对象保存后读取:
    null
    
  • 相关阅读:
    springboot自定义注解
    springboot2.3+mybatis+pageHelper
    免费好用的mysql客户端
    springboot2.3+mybatis-plus+mysql8.0
    b站“视频评论区”抽奖 讲解(含JS源码)
    JS实现b站动态抽奖“公平”方案——动态+转发
    JS实现b站动态转发抽奖(小人数)新方案讲解
    C#爬虫(Selenium和WeiAPI)
    C#时间戳转换
    Quartz.net配置文件出现的坑
  • 原文地址:https://www.cnblogs.com/liangjingfu/p/10019175.html
Copyright © 2011-2022 走看看