热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

java调用类_Java的四种引用类型

在Java中提供了四个级别的引用:强引用,软引用,弱引用和虚引用。在这四个引用类型中,只有强引用FinalReference

在Java中提供了四个级别的引用:强引用,软引用,弱引用和虚引用。在这四个引用类型中,只有强引用FinalReference类是包内可见,其他三种引用类型均为public,可以在应用程序中直接使用。引用类型的类结构如图所示。

1.强引用

Java中的引用,类似C语言中最难的指针。(我是C语言入门编程,指针的概念还是很深入我心。)通过引用,可以对堆中的对象进行操作。如:

StringBuffer stringBuffer = new StringBuffer("Helloword");

变量str指向StringBuffer实例所在的堆空间,通过str可以操作该对象。

强引用的特点:

强引用可以直接访问目标对象。

强引用所指向的对象在任何时候都不会被系统回收。JVM宁愿抛出OOM异常,也不会回收强引用所指向的对象。

强引用可能导致内存泄漏。

2.软引用

软引用是除了强引用外,最强的引用类型。可以通过java.lang.ref.SoftReference使用软引用。一个持有软引用的对象,不会被JVM很快回收,JVM会根据当前堆的使用情况来判断何时回收。当堆使用率临近阈值时,才会去回收软引用的对象。因此,软引用可以用于实现对内存敏感的高速缓存。

SoftReference的特点是它的一个实例保存对一个Java对象的软引用, 该软引用的存在不妨碍垃圾收集线程对该Java对象的回收。也就是说,一旦SoftReference保存了对一个Java对象的软引用后,在垃圾线程对 这个Java对象回收前,SoftReference类所提供的get()方法返回Java对象的强引用。一旦垃圾线程回收该Java对象之后,get()方法将返回null。

下面举一个例子说明软引用的使用方法。

在你的IDE设置参数 -Xmx2m -Xms2m规定堆内存大小为2m。

@Test

public void test3(){

MyObject obj = new myObject();

SoftReference sf &#61; new SoftReference<>(obj);

obj &#61; null;

System.gc();

// byte[] bytes &#61; new byte[1024*100];

// System.gc();

System.out.println("是否被回收"&#43;sf.get());

}

运行结果&#xff1a;

是否被回收cn.zyzpp.MyObject&#64;42110406

打开被注释掉的new byte[1024*100]语句&#xff0c;这条语句请求一块大的堆空间&#xff0c;使堆内存使用紧张。并显式的再调用一次GC&#xff0c;结果如下&#xff1a;

是否被回收null

说明在系统内存紧张的情况下&#xff0c;软引用被回收。

3.弱引用

弱引用是一种比软引用较弱的引用类型。在系统GC时&#xff0c;只要发现弱引用&#xff0c;不管系统堆空间是否足够&#xff0c;都会将对象进行回收。在java中&#xff0c;可以用java.lang.ref.WeakReference实例来保存对一个Java对象的弱引用。

public void test3(){

MyObject obj &#61; new MyObject();

WeakReference sf &#61; new WeakReference(obj);

obj &#61; null;

System.out.println("是否被回收"&#43;sf.get());

System.gc();

System.out.println("是否被回收"&#43;sf.get());

}

运行结果&#xff1a;

是否被回收cn.zyzpp.MyObject&#64;42110406

是否被回收null

软引用&#xff0c;弱引用都非常适合来保存那些可有可无的缓存数据&#xff0c;如果这么做&#xff0c;当系统内存不足时&#xff0c;这些缓存数据会被回收&#xff0c;不会导致内存溢出。而当内存资源充足时&#xff0c;这些缓存数据又可以存在相当长的时间&#xff0c;从而起到加速系统的作用。

4.虚引用

虚引用是所有类型中最弱的一个。一个持有虚引用的对象&#xff0c;和没有引用几乎是一样的&#xff0c;随时可能被垃圾回收器回收。当试图通过虚引用的get()方法取得强引用时&#xff0c;总是会失败。并且&#xff0c;虚引用必须和引用队列一起使用&#xff0c;它的作用在于跟踪垃圾回收过程。

当垃圾回收器准备回收一个对象时&#xff0c;如果发现它还有虚引用&#xff0c;就会在垃圾回收后&#xff0c;销毁这个对象&#xff0c;将这个虚引用加入引用队列。程序可以通过判断引用队列中是否已经加入了虚引用&#xff0c;来了解被引用的对象是否将要被垃圾回收。如果程序发现某个虚引用已经被加入到引用队列&#xff0c;那么就可以在所引用的对象的内存被回收之前采取必要的行动。

public void test3(){

MyObject obj &#61; new MyObject();

ReferenceQueue referenceQueue &#61; new ReferenceQueue<>();

PhantomReference sf &#61; new PhantomReference<>(obj,referenceQueue);

obj &#61; null;

System.out.println("是否被回收"&#43;sf.get());

System.gc();

System.out.println("是否被回收"&#43;sf.get());

}

运行结果&#xff1a;

是否被回收null

是否被回收null

对虚引用的get()操作&#xff0c;总是返回null&#xff0c;因为sf.get()方法的实现如下&#xff1a;

public T get() {

return null;

}

5.WeakHashMap类及其实现

WeakHashMap类在java.util包内&#xff0c;它实现了Map接口&#xff0c;是HashMap的一种实现&#xff0c;它使用弱引用作为内部数据的存储方案。WeakHashMap是弱引用的一种典型应用&#xff0c;它可以作为简单的缓存表解决方案。

一下两段代码分别使用WeakHashMap和HashMap保存大量的数据&#xff1a;

&#64;Test

public void test4(){

Map map;

map &#61; new WeakHashMap();

for (int i &#61;0;i<10000;i&#43;&#43;){

map.put("key"&#43;i,new byte[i]);

}

// map &#61; new HashMap();

// for (int i &#61;0;i<10000;i&#43;&#43;){

// map.put("key"&#43;i,new byte[i]);

//}

}

使用-Xmx2M限定堆内存&#xff0c;使用WeakHashMap的代码正常运行结束&#xff0c;而使用HashMap的代码段抛出异常

java.lang.OutOfMemoryError: Java heap space

由此可见&#xff0c;WeakHashMap会在系统内存紧张时使用弱引用&#xff0c;自动释放掉持有弱引用的内存数据。

但如果WeakHashMap的key都在系统内持有强引用&#xff0c;那么WeakHashMap就退化为普通的HashMap&#xff0c;因为所有的表项都无法被自动清理。



推荐阅读
  • 本文整理了Java面试中常见的问题及相关概念的解析,包括HashMap中为什么重写equals还要重写hashcode、map的分类和常见情况、final关键字的用法、Synchronized和lock的区别、volatile的介绍、Syncronized锁的作用、构造函数和构造函数重载的概念、方法覆盖和方法重载的区别、反射获取和设置对象私有字段的值的方法、通过反射创建对象的方式以及内部类的详解。 ... [详细]
  • LeetCode笔记:剑指Offer 41. 数据流中的中位数(Java、堆、优先队列、知识点)
    本文介绍了LeetCode剑指Offer 41题的解题思路和代码实现,主要涉及了Java中的优先队列和堆排序的知识点。优先队列是Queue接口的实现,可以对其中的元素进行排序,采用小顶堆的方式进行排序。本文还介绍了Java中queue的offer、poll、add、remove、element、peek等方法的区别和用法。 ... [详细]
  • 个人学习使用:谨慎参考1Client类importcom.thoughtworks.gauge.Step;importcom.thoughtworks.gauge.T ... [详细]
  • JDK源码学习之HashTable(附带面试题)的学习笔记
    本文介绍了JDK源码学习之HashTable(附带面试题)的学习笔记,包括HashTable的定义、数据类型、与HashMap的关系和区别。文章提供了干货,并附带了其他相关主题的学习笔记。 ... [详细]
  • HashMap的相关问题及其底层数据结构和操作流程
    本文介绍了关于HashMap的相关问题,包括其底层数据结构、JDK1.7和JDK1.8的差异、红黑树的使用、扩容和树化的条件、退化为链表的情况、索引的计算方法、hashcode和hash()方法的作用、数组容量的选择、Put方法的流程以及并发问题下的操作。文章还提到了扩容死链和数据错乱的问题,并探讨了key的设计要求。对于对Java面试中的HashMap问题感兴趣的读者,本文将为您提供一些有用的技术和经验。 ... [详细]
  • 微信官方授权及获取OpenId的方法,服务器通过SpringBoot实现
    主要步骤:前端获取到code(wx.login),传入服务器服务器通过参数AppID和AppSecret访问官方接口,获取到OpenId ... [详细]
  • Python语法上的区别及注意事项
    本文介绍了Python2x和Python3x在语法上的区别,包括print语句的变化、除法运算结果的不同、raw_input函数的替代、class写法的变化等。同时还介绍了Python脚本的解释程序的指定方法,以及在不同版本的Python中如何执行脚本。对于想要学习Python的人来说,本文提供了一些注意事项和技巧。 ... [详细]
  • 模板引擎StringTemplate的使用方法和特点
    本文介绍了模板引擎StringTemplate的使用方法和特点,包括强制Model和View的分离、Lazy-Evaluation、Recursive enable等。同时,还介绍了StringTemplate语法中的属性和普通字符的使用方法,并提供了向模板填充属性的示例代码。 ... [详细]
  • Java程序设计第4周学习总结及注释应用的开发笔记
    本文由编程笔记#小编为大家整理,主要介绍了201521123087《Java程序设计》第4周学习总结相关的知识,包括注释的应用和使用类的注释与方法的注释进行注释的方法,并在Eclipse中查看。摘要内容大约为150字,提供了一定的参考价值。 ... [详细]
  • Android工程师面试准备及设计模式使用场景
    本文介绍了Android工程师面试准备的经验,包括面试流程和重点准备内容。同时,还介绍了建造者模式的使用场景,以及在Android开发中的具体应用。 ... [详细]
  • 本文讨论了在VMWARE5.1的虚拟服务器Windows Server 2008R2上安装oracle 10g客户端时出现的问题,并提供了解决方法。错误日志显示了异常访问违例,通过分析日志中的问题帧,找到了解决问题的线索。文章详细介绍了解决方法,帮助读者顺利安装oracle 10g客户端。 ... [详细]
  • 本文讨论了微软的STL容器类是否线程安全。根据MSDN的回答,STL容器类包括vector、deque、list、queue、stack、priority_queue、valarray、map、hash_map、multimap、hash_multimap、set、hash_set、multiset、hash_multiset、basic_string和bitset。对于单个对象来说,多个线程同时读取是安全的。但如果一个线程正在写入一个对象,那么所有的读写操作都需要进行同步。 ... [详细]
  • Centos下安装memcached+memcached教程
    本文介绍了在Centos下安装memcached和使用memcached的教程,详细解释了memcached的工作原理,包括缓存数据和对象、减少数据库读取次数、提高网站速度等。同时,还对memcached的快速和高效率进行了解释,与传统的文件型数据库相比,memcached作为一个内存型数据库,具有更高的读取速度。 ... [详细]
  • 本文介绍了在Android开发中使用软引用和弱引用的应用。如果一个对象只具有软引用,那么只有在内存不够的情况下才会被回收,可以用来实现内存敏感的高速缓存;而如果一个对象只具有弱引用,不管内存是否足够,都会被垃圾回收器回收。软引用和弱引用还可以与引用队列联合使用,当被引用的对象被回收时,会将引用加入到关联的引用队列中。软引用和弱引用的根本区别在于生命周期的长短,弱引用的对象可能随时被回收,而软引用的对象只有在内存不够时才会被回收。 ... [详细]
  • Hibernate延迟加载深入分析-集合属性的延迟加载策略
    本文深入分析了Hibernate延迟加载的机制,特别是集合属性的延迟加载策略。通过延迟加载,可以降低系统的内存开销,提高Hibernate的运行性能。对于集合属性,推荐使用延迟加载策略,即在系统需要使用集合属性时才从数据库装载关联的数据,避免一次加载所有集合属性导致性能下降。 ... [详细]
author-avatar
w3shuajiang2
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有