java方法引用有什么用(java引用方式有哪些)

技术Java中引用方法有哪些这篇文章主要介绍“Java中引用方法有哪些”,在日常操作中,相信很多人在Java中引用方法有哪些问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java中引用方法

本文主要介绍“Java中有哪些引用方法”。在日常操作中,我相信很多人对Java中的引用方法有什么问题有疑问。边肖查阅了各种资料,整理出简单易用的操作方法,希望能帮助大家解答“Java中有哪些引用方法”的疑惑!接下来,请和边肖一起学习!

java中有四种引用方法,适用于不同的场景。理解虚拟引用并结合文本和代码很重要。

00-1010强引用对象不会被垃圾收集器回收,JVM宁愿抛出OOM也不回收强引用对象;

mm=NewM();00-1010当堆空间足够时,GC不会回收软引用对象。当堆空间不足以分配新空间时,触发GC将回收这部分对象,通常用于缓存和其他字段。对缓存对象使用软引用,空间不足时释放这部分空间,需要再次使用时从DB重新加载。

此外,软引用可以与ReferenceQueue一起使用。如果软引用引用的对象被垃圾收集,JVM会将软引用添加到与之关联的引用队列中。

/**

*软引用:一般用在缓存中,只要空间不足,GC运行时就会回收。

*操作参数-xmx200 m-xx3360打印气相色谱

* created bytefoxx 2021/03/0117:06

**/

publicclassTestSoftReference{

publicationstatinvitmain(String[]AGS)throwsInterruptedException {

//1亿缓存数据

byte[]cacheData=new byte[100 * 1024 * 1024];

//用软引用保存缓存数据

SoftReferencebyte[]cache ref=newSoftReference(cache data);

//移除缓存数据的强引用

cacheData=null

System.out.println(第一次GC前的缓存数据);

System.out.println('在第一个GC' cacheRef.get()之前);

//GC后检查对象的回收状态。

system . GC();

//等待GC

thread . sleep(500);

System.out.println(第一次GC后的缓存数据);

System.out.println('在第一个GC' cacheRef.get()之后);

//分配一个120M的对象,看缓存对象的回收。

字节[ne]

wData = new byte[120 * 1024 * 1024];
        System.out.println("分配后" + cacheData);
        System.out.println("分配后" + cacheRef.get());
    }
}
console==>
[GC (Allocation Failure)  4120K->1055K(15872K), 0.0016237 secs]
[Full GC (Allocation Failure)  1055K->1054K(15872K), 0.0015426 secs]
第一次GC前null
第一次GC前[B@1973e9b
[Full GC (System.gc())  103583K->103455K(118340K), 0.0015559 secs]
第一次GC后null
第一次GC后[B@1973e9b
[GC (Allocation Failure)  105575K->103455K(198016K), 0.0001733 secs]
[Full GC (Allocation Failure)  103455K->103455K(198016K), 0.0011860 secs]
[Full GC (Allocation Failure)  103455K->819K(198016K), 0.0012080 secs]
分配后null
分配后null

弱引用

弱引用的引用对象在每次 GC 时,不管当前堆内存大小,都会将这个对象清除。如果此对象偶尔使用,并且希望需要用到的时候可以获取到,但是又不希望影响这个对象的回收,就可以使用弱引用来描述对象。

当然弱引用也可以结合事件队列使用。

/**
 * 弱引用:如果对象时偶尔使用,并且希望使用的时候就能获取到(get),但是又不想影响此对象的垃圾收集
 * 可以引入队列
 * Created by etfox on 2021/03/01 17:59
 **/
public class TestWeakReference {
    public static void main(String[] args) throws InterruptedException {
        //100M的缓存数据
        byte[] cacheData = new byte[100 * 1024 * 1024];
        //将缓存数据用软引用持有
        WeakReference<byte[]> cacheRef = new WeakReference<>(cacheData);
        System.out.println("第一次GC前" + cacheData);
        System.out.println("第一次GC前" + cacheRef.get());
        //进行一次GC后查看对象的回收情况
        System.gc();
        //等待GC
        Thread.sleep(500);
        System.out.println("第一次GC后" + cacheData);
        System.out.println("第一次GC后" + cacheRef.get());
        //将缓存数据的强引用去除
        cacheData = null;
        System.gc();
        //等待GC
        Thread.sleep(500);
        System.out.println("第二次GC后" + cacheData);
        System.out.println("第二次GC后" + cacheRef.get());
    }
}
console==>
[GC (Allocation Failure)  3912K->1025K(15872K), 0.0016372 secs]
[Full GC (Allocation Failure)  1025K->1024K(15872K), 0.0014157 secs]
第一次GC前[B@1973e9b
第一次GC前[B@1973e9b
[Full GC (System.gc())  103723K->103456K(118340K), 0.0016463 secs]
第一次GC后[B@1973e9b
第一次GC后[B@1973e9b
[Full GC (System.gc())  105601K->1056K(198016K), 0.0012771 secs]
第二次GC后null
第二次GC后null

虚引用

虚引用,顾名思义是虚幻的,虚引用的对象并不能在 get 的时候获取到它。它也在我们日常开发中没有适用的场景,它的主要作用是用来跟踪一个对象的生命周期 (通常来说是直接内存 [JDK1.5 Java 中除了由 JVM 管理的空间,还可以在内存中直接分配对象]中的对象),一般使用在 JVM 的开发中,主要用来管理直接内存,因为直接内存通常 GC 无法管理这一块内存(C++ delete 完事),需要特殊处理。

例如 NIO 的 ByteBuffer.allocateDirect(1024); 分配内存到直接内存空间中,通常来说从网卡中读取的数据,由操作系统读取到直接内存中,在需要使用的时候,需要拷贝到 JVM 堆空间中,如果不使用 allocateDirect 就需要一个拷贝的过程,这是非常消耗时间的,

// |-- ---| | --------| |------------|
// | 网卡 | ==> | 直接内存 | == copy ==> | JVM 堆空间 |
// |--- --| | ------- | |------------|

使用直接存内存省略了拷贝的过程,俗称 nio 的 zero copy,但是直接内存中的对象在不需要使用的时候无法通过正常 GC 过程去管理这一块空间,所以用到了虚引用,

解释:

虚引用需要配合一个事件队列一起使用,JVM GC 的时候并不是说把虚引用的引用清理掉完事,而是说会把虚引用的引用放到事件队列当中,垃圾回收线程会时不时的去检查这个事件队列,看一下引用的回收过程需不需要做一些后续善后处理(例如清理直接内存中的对象,这玩意儿由实现人去弄)这就是虚引用的作用和含义了。

/**
 * 虚引用:可以通过队列跟踪一个对象的生命周期,一般在写 JVM 相关的时候才会用到虚引用,主要用来管理直接内存(C++ delete 一下子完事)
 * -Xmx20m -XX:+PrintGC
 * Created by etfox on 2021/03/03 12:14
 **/
public class TestPhantomReference {
    private static final List<Object> LIST = new LinkedList<>();
    private static final ReferenceQueue<M> QUEUE = new ReferenceQueue<>();
    public static void main(String[] args) throws InterruptedException {
        final PhantomReference<M> phantomReference = new PhantomReference<>(new M(), QUEUE);
        // 永远都会返回 null
        System.out.println(phantomReference.get());
        // ByteBuffer.allocateDirect(1024); 分配内存到操作系统的空间,直接内存的空间, JDK 1.5
        // 通常从网卡读取的数据,通常由系统读取到直接内存里面,如果想用,需要拷贝到 JVM 堆空间里
        // 如果不使用 allocateDirect(直接内存) 就需要一个拷贝的过程,是非常消耗时间的
        // |-- ---|     | --------|             |------------|
        // | 网卡  | ==> | 直接内存 | == copy ==> |  JVM 堆空间 |
        // |--- --|     | ------- |             |------------|
        // 使用直接内存省略了拷贝的过程,俗称 nio zero copy
        // 但是直接内存中的对象在不再需要的时候无法由 JVM 去 GC 清理内存,所以用到了虚引用
        // 虚引用需要和一个队列一起使用,JVM GC 时并不是说会把虚引用的引用清理,而是说会把虚引用的引用放到事件队列中
        // 垃圾回收线程可以时不时的检查这个事件队列,看一下这个引用的回收过程需不需要做一些善后处理(例如清理直接内存的那个对象)
        // 这就是虚引用的作用和含义
        ByteBuffer b = ByteBuffer.allocateDirect(1024);
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    LIST.add(new byte[1024 * 1024]);
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(phantomReference.get());
                }
            }
        }).start();
        // 模拟垃圾回收线程
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    Reference<? extends M> poll = QUEUE.poll();
                    if (poll != null) {
                        System.out.println("虚引用对象被 JVM 回收了 " + poll);
                    }
                }
            }
        }).start();
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    public static class M {
        @Override
        protected void finalize() throws Throwable {
            System.out.println("当对象将被回收时, GC 会调用当前方法");
        }
    }
}
console==>
null
[GC (Allocation Failure)  3493K->1061K(15872K), 0.0017311 secs]
当对象将被回收时, GC 会调用当前方法
null
null
null
[GC (Allocation Failure)  4483K->4132K(15872K), 0.0020184 secs]
null
null
null
null
[GC (Allocation Failure)  8299K->8228K(15872K), 0.0017350 secs]
null
null
null
null
[GC (Allocation Failure)  12401K->12324K(17928K), 0.0016853 secs]
[Full GC (Allocation Failure)  12324K->12324K(17928K), 0.0011354 secs]
虚引用对象被 JVM 回收了 java.lang.ref.PhantomReference@d5fbc1
null
null
null
null
null
[Full GC (Allocation Failure)  17599K->17445K(19840K), 0.0019903 secs]
null
[Full GC (Allocation Failure)  18524K->18469K(19840K), 0.0011629 secs]
[Full GC (Allocation Failure)  18469K->18232K(19840K), 0.0022320 secs]
Exception in thread "Thread-0" java.lang.OutOfMemoryError: Java heap space
	at com.pangu.TestPhantomReference$1.run(TestPhantomReference.java:41)
	at java.lang.Thread.run(Thread.java:748)

到此,关于“Java中引用方法有哪些”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!

内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/156266.html

(0)

相关推荐

  • 条条大路通罗马下一句,条条大路通罗马中国版名言

    技术条条大路通罗马下一句,条条大路通罗马中国版名言大道是前人修好的条条大路通罗马下一句,小路需要自己去走,我不喜欢品尝别人的胜利果实,却喜欢独僻蹊径去闯出自己的一条小路。2.独自漫步在小巷,雪白的路灯洒着醒目的光,灰淡的

    生活 2021年10月22日
  • css3中设置文本阴影的属性是(css3球体掉落动画带阴影效果)

    技术css3怎么实现图片阴影效果这篇文章主要讲解了“css3怎么实现图片阴影效果”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“css3怎么实现图片阴影效果”吧!css3实

    攻略 2021年12月16日
  • 抖音点赞3元100个,抖音怎么刷点赞上热门

    技术抖音点赞3元100个,抖音怎么刷点赞上热门大家务必要可以客观的应对抖音短视频粉丝领域的收费标准价钱规范,并并不是贵的才算是好的自然也并不一定划算的价钱全是不靠谱的,只是要可以融合自身的要求选择专业靠谱的服务平台,而且

    测评 2021年10月26日
  • 怎么理解ADO.NET数据表

    技术怎么理解ADO.NET数据表这篇文章主要讲解了“怎么理解ADO.NET数据表”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“怎么理解ADO.NET数据表”吧!ADO.N

    攻略 2021年12月3日
  • C#与C++哪个更强

    技术C#与C++哪个更强这篇文章主要介绍“C#与C++哪个更强”,在日常操作中,相信很多人在C#与C++哪个更强问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”C#与C++哪个更强”的疑惑有

    攻略 2021年11月29日
  • 燕麦片的好处,燕麦有什么医疗保健价值

    技术燕麦片的好处,燕麦有什么医疗保健价值关于燕麦的医疗保健作用,我国古籍《唐本草》就记载有燕麦对产期妇女的催乳作用,迄今我国西南地区的彝族等少数民族仍在妇女产期和哺乳期喝燕麦汤用以催乳和健身燕麦片的好处。自20世纪80年

    生活 2021年10月30日