iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >Java中引用方法有哪些
  • 672
分享到

Java中引用方法有哪些

2023-06-22 05:06:40 672人浏览 薄情痞子
摘要

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

这篇文章主要介绍“Java中引用方法有哪些”,在日常操作中,相信很多人在Java中引用方法有哪些问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java中引用方法有哪些”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

java 中的 4 种引用方式,适用于不同的场景,重点需要理解虚引用,结合文字和代码

强引用

被强引用的对象,不会被垃圾回收器回收,JVM 宁愿抛出 OOM 也不会去回收被强引用的对象;

M m = new M();

软引用

当堆空间够用时,GC 不会对软引用的对象进行回收,当堆空间不足以分配新的空间时,触发 GC 就会对这部分对象进行回收,通常用在缓存等领域。将缓存对象使用软引用,空间不足的时候释放这部分空间,需要再次使用的时候,重新从 DB 中加载即可。

另外软引用可以配合队列(ReferenceQueue) 来使用,如果软引用引用的对象被垃圾回收,JVM 会把软引用加入到与之关联的引用队列中。

public class TestSoftReference {    public static void main(String[] ags) throws InterruptedException {        //100M的缓存数据        byte[] cacheData = new byte[100 * 1024 * 1024];        //将缓存数据用软引用持有        SoftReference<byte[]> cacheRef = new SoftReference<>(cacheData);        //将缓存数据的强引用去除        cacheData = null;        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());        //在分配一个120M的对象,看看缓存对象的回收情况        byte[] newData = 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 时,不管当前堆内存大小,都会将这个对象清除。如果此对象偶尔使用,并且希望需要用到的时候可以获取到,但是又不希望影响这个对象的回收,就可以使用弱引用来描述对象。

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

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

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 会调用当前方法nullnullnull[GC (Allocation Failure)  4483K->4132K(15872K), 0.0020184 secs]nullnullnullnull[GC (Allocation Failure)  8299K->8228K(15872K), 0.0017350 secs]nullnullnullnull[GC (Allocation Failure)  12401K->12324K(17928K), 0.0016853 secs][Full GC (Allocation Failure)  12324K->12324K(17928K), 0.0011354 secs]虚引用对象被 JVM 回收了 java.lang.ref.PhantomReference@d5fbc1nullnullnullnullnull[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 spaceat com.pangu.TestPhantomReference$1.run(TestPhantomReference.java:41)at java.lang.Thread.run(Thread.java:748)

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

--结束END--

本文标题: Java中引用方法有哪些

本文链接: https://www.lsjlt.com/news/302604.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Java中引用方法有哪些
    这篇文章主要介绍“Java中引用方法有哪些”,在日常操作中,相信很多人在Java中引用方法有哪些问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java中引用方法有哪些”的疑惑有所帮助!接下来,请跟着小编一起来...
    99+
    2023-06-22
  • java8中有哪些方法引用
    本篇文章给大家分享的是有关java8中有哪些方法引用,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。Java是什么Java是一门面向对象编程语言,可以编写桌面应用程序、Web应用...
    99+
    2023-06-14
  • Java中有哪些引用类型
    Java中有哪些引用类型?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。强引用强引用是最常用的引用类型,如下所示,new Object()会创建一个Object对象并存储在堆...
    99+
    2023-06-14
  • java中索引有哪些
    java中的索引有:1.哈希索引,以键-值存储数据的结构;2.空间数据索引,可以用作地理数据存储的索引;3.全文索引,特殊类型的索引;java中的索引有以下几种哈希索引java中哈希索引是一种以键-值存储数据的结构,哈希索引可以将哈希码存储...
    99+
    2024-04-02
  • java中常用的方法有哪些
    Java中常用的方法有以下几种:1. String类的方法:常用的字符串操作方法,如substring()、indexOf...
    99+
    2023-09-22
    java
  • java中Object有哪些公用方法
    小编给大家分享一下java中Object有哪些公用方法,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!Object有哪些公用方法?clone() 创建斌返回此对象的副本equals() 判断...
    99+
    2024-04-02
  • java中indexof方法有哪些
    在Java中,`indexOf`方法有以下几种形式:1. `int indexOf(int ch)`:返回指定字符在字符串中第一次出...
    99+
    2023-08-30
    java
  • HTML中引入CSS的方法有哪些
    这篇文章主要讲解了“HTML中引入CSS的方法有哪些”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“HTML中引入CSS的方法有哪些”吧!行内引入直接在标签中加入 CSS 样式。若使用此方法过...
    99+
    2023-06-27
  • python中引入库的方法有哪些
    在Python中,引入库的方法有以下几种: 使用`import`语句引入整个库: import math 使用`import...
    99+
    2023-10-26
    python
  • Java开发中的索引算法有哪些?
    在Java开发中,索引算法是一个非常重要的概念。索引算法可以帮助我们快速地查找数据,提高数据检索的效率。在本文中,我们将介绍Java开发中常用的一些索引算法,并附上相应的演示代码。 一、二分查找算法 二分查找算法是一种常见的索引算法,也叫...
    99+
    2023-11-13
    索引 编程算法 开发技术
  • java中optional的常用方法有哪些
    这篇文章主要介绍了java中optional的常用方法有哪些的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇java中optional的常用方法有哪些文章都会有所收获,下面我们一起来看看吧。前言Java中的Opt...
    99+
    2023-07-05
  • java中stringbuffer的使用方法有哪些
    Java中StringBuffer的使用方法有以下几种:1. 创建StringBuffer对象:- 使用空参构造方法创建一个空的St...
    99+
    2023-08-25
    java stringbuffer
  • java中velocity的使用方法有哪些
    在Java中使用Velocity模板引擎有以下几种方法:1. 使用Velocity的原始API:通过创建Velocity引擎实例,加...
    99+
    2023-09-16
    java velocity
  • java中printStackTrace()方法的作用有哪些
    Java中的printStackTrace()方法用于打印异常的堆栈跟踪信息。其作用包括:1. 打印异常的堆栈跟踪信息:printS...
    99+
    2023-09-11
    java
  • Java中String类有哪些使用方法
    这篇文章给大家分享的是有关Java中String类有哪些使用方法的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。StringString类:代表字符串,提供了开发中常用的字符串处理的方法,如:求字符串的长度、截取字...
    99+
    2023-06-29
  • java中stringbuffer的常用方法有哪些
    append(String str): 将指定字符串添加到StringBuffer的末尾。2. insert(int offset,...
    99+
    2023-10-18
    java
  • java中有哪些成员方法
    java中有哪些成员方法?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。Java可以用来干什么Java主要应用于:1. web开发;2. Android开发;3. 客户端开发;4...
    99+
    2023-06-14
  • java中枚举方法有哪些
    这篇文章将为大家详细讲解有关java中枚举方法有哪些,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。Java有哪些集合类Java中的集合主要分为四类:1、List列表:有序的,可重复的;2、Q...
    99+
    2023-06-14
  • linux的引导方法有哪些
    这篇文章主要介绍“linux的引导方法有哪些”,在日常操作中,相信很多人在linux的引导方法有哪些问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”linux的引导方法有哪些”的疑惑有所帮助!接下来,请跟着小编...
    99+
    2023-06-10
  • java中有哪些规则引擎
    这期内容当中小编将会给大家带来有关java中有哪些规则引擎,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。Java的特点有哪些Java的特点有哪些1.Java语言作为静态面向对象编程语言的代表,实现了面向对...
    99+
    2023-06-14
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作