`
backend-develop
  • 浏览: 24107 次
社区版块
存档分类
最新评论

关于Java引用,你必须知道这些

    博客分类:
  • Java
阅读更多

引用

Java 虚拟机接管了所有的内存分配与回收工作,极大地减少了程序员的工作量和错误率。GC 在回收内存时,通常采用被称为可达性分析的算法判断一个对象是否可以回收。而在可达性分析中,对象的引用有着决定性的作用。在下图中,GC 从 GC Roots 开始顺着引用链往下寻找对象,发现当前有引用的对象为object 1、object 2、object 3、object 4,而object 5、object 6、object 7虽然互相之间有引用但已经无法从外部引用到。因此,图中 object 1-4 为存活的对象,而 object 5-7 为可回收的对象。

 

虽然 GC 能够完成垃圾收集工作,但是仍然无法避免 out of memory 。一方面在开发过程中需要注意不再使用的引用设为 null 来释放引用的对象,另一方面也需要从对象引用的角度考虑使用合适的引用类型更好地管理对象内存。

 

 

引用的类型

Java 有4种类型的引用:strong(强引用),soft(软引用),weak(弱引用)和 phantom(虚引用)。

 

强引用:强引用是在 Java 中的普通引用。任何时候我们创建一个新的对象,默认情况下创建一个强引用。例如类的静态变量,从类被初始化之后便已经分配内存,作为强引用对象不能被 GC 回收,需要等待虚拟机退出或类被卸载才能释放引用被 GC 回收。

 

弱引用:弱引用无法保证对象一定存活于内存中,被弱引用关联的对象只能生存到下一次垃圾收集发生之前。我们可以使用 WeakReference 类来实现弱引用。

 

 

软引用:软引用比弱引用稍强一点,垃圾收集发生时弱引用一定会被回收,而软引用会请求 GC 保留自己除非没有其他选择,可以理解为只在将要发生内存溢出时 GC 才会回收软引用。我们可以使用 SoftReference 类来实现软引用。

 

 

虚引用:一个对象是否有虚引用的存在,完全不会对其生存时间构成影响,也无法通过虚引用来取得一个对象实例。为一个对象设置虚引用关联的唯一目的就是能在这个对象被 GC 回收时收到一个系统通知。我们可以使用 PhantomReference 类来实现虚引用。当 GC 准备回收一个对象时,如果发现它还有虚引用,就会在回收对象的内存之前,把这个虚引用加入到与之关联的引用队列中。开发者可以通过判断引用队列中是否包含对象来判断对象是否即将被回收,可以在回收之前做些处理。

 

 

引用队列:如果引用关联了引用队列,则 GC 回收对象内存的时候会把引用加入到引用队列中。当引用队列中包含引用时,意味着引用指向的堆内存中的对象被回收。

 

 

引用的应用

构建缓存

使用软引用可以用于创建 Java 本地高速缓存,只要内存仍然够用缓存就不会被删除,而一旦内存紧张即将溢出时,GC 会删除部分缓存释放内存。例如,创建比较耗时影响性能的数据对象、一段时间内可以重复使用的资源、不常变化的数据等,都可以使用软引用构建缓存,既能保证读取性能,又不会导致内存溢出。

 

WeakHashMap

WeakHashMap 是以弱引用键实现的哈希表。当 WeakHashMap 中的键不再被强引用使用时,GC 下次回收垃圾时将回收此键。WeakHashMap 中的键被回收后,哈希表的条目也会被 GC 回收。因此,WeakHashMap 可以用于临时存储一些不需要长时间使用的对象,可以有效避免内存溢出。

 

 

总结

Java 开发中最常用的引用是强引用,通过new创建对象得到强引用。强引用会阻止 GC 释放对象内存,长时间运行容易导致内存溢出。在开发中,对于强引用变量在使用完毕后应把值设置为 null 来帮助 GC 进行垃圾回收。在 Java 中还有另外三种引用类型,弱引用、软引用和虚引用。弱引用和软引用可以用于构建缓存和避免内存泄露,虚引用可以用于获知对象将被回收的通知并进行处理。

 

四种引用类型的对比如下:

 

原文地址:关于Java引用,你必须知道这些

0
0
分享到:
评论
1 楼 weiweiweiyi 2017-03-27  
不是分代收集算法吗

相关推荐

    java必须知道的东西

    以下是一些Java必须知道的关键知识点: 1. **面向对象特性**: - **抽象**:抽象是忽略不重要的细节,专注于对象的主要功能。它分为过程抽象(如方法)和数据抽象(如类)。Java中的抽象类和接口是抽象的体现。 -...

    JAVA基础入门资料,J2SE入门资料,JAVA培训第一课,JAVA初学者资料,JAVA学习者必须知道的问题汇总

    这份"JAVA基础入门资料,J2SE入门资料,JAVA培训第一课,JAVA初学者资料,JAVA学习者必须知道的问题汇总"是绝佳的学习资源,涵盖了Java编程的基础知识,将帮助你快速进入Java的世界。 首先,让我们从Java的基础开始...

    Java引用类型编程开发技术共13页.pdf.zip

    在这里,我们将对Java引用类型的一些关键知识点进行详细的阐述。 1. 类(Class):Java是一种面向对象的语言,类是创建对象的蓝图。它定义了对象的属性(数据成员)和行为(方法)。通过定义类,我们可以创建具有...

    Java中对象与引用对象的关系

    Java中对象与引用对象的关系 在 Java 中,对象和引用对象的关系是一个非常重要的概念。从宏观的角度来看,对象是类的实例。例如,我们可以定义一个名为 Someone 的类,代表一些人(通过指定年龄、性别、性格等基本...

    你必须知道的261个JAVA语言问题

    《你必须知道的261个JAVA语言问题》这本书涵盖了Java编程中遇到的各种常见问题,旨在帮助开发者深入理解Java的核心概念,提高编程技能。下面我们将详细探讨一些Java语言的关键知识点。 1. **基础语法** - 变量声明...

    java的传值与传引用详解

    既然争论中提到了引用这个东西,为了搞清楚这个问题,我们必须要知道引用是什么。  简单的说,引用其实就像是一个对象的名字或者别名 (alias),一个对象在内存中会请求一块空间来保存数据,根据对象的大小,它可能...

    关于Java对象序列化您不知道的5件事Java开发Java

    以下是五个可能不为人知的关于Java对象序列化的知识点,这些知识点对于深入理解Java开发至关重要。 1. **序列化的作用**: Java对象序列化的主要目的是将对象的状态持久化,这样即使程序关闭,对象的状态也可以...

    你必须知道的java类面试题

    Java 类是Java编程语言的核心组成部分,对于...以上就是Java类面试中可能遇到的一些核心知识点,掌握这些概念和技术将有助于你在面试中表现出色。通过不断实践和学习,你可以深化对Java类的理解,进一步提升编程能力。

    JAVA基础易错总结(50%你不知道)

    "JAVA基础易错总结(50%你不知道)"这份资料,由大鹏历时5个月精心原创,旨在揭示那些易被忽视或误解的Java基础知识,帮助开发者提高代码质量和效率。 首先,我们关注Java的基础语法。例如,虽然大部分开发者了解...

    java源码包---java 源码 大量 实例

     Java局域网通信——飞鸽传书源代码,大家都知道VB版、VC版还有Delphi版的飞鸽传书软件,但是Java版的确实不多,因此这个Java文件传输实例不可错过,Java网络编程技能的提升很有帮助。 Java聊天程序,包括服务端和...

    java面试 java书籍

    Java是一种广泛使用的面向对象的编程语言,以其跨平台、高性能和丰富的类库而备受赞誉。在IT行业,尤其是软件开发领域...通过阅读这些书籍,并结合实际项目经验,你可以为Java面试做好充分准备,展现出扎实的技术功底。

    Java 自动加载JAR文件并运行其中的类方法

    它是一个归档文件格式,包含了一个或多个.class文件,这些文件构成了Java应用程序的可执行代码。JAR文件可以包含一个清单(MANIFEST.MF)文件,用于指定启动类和其他元数据。 要自动加载JAR文件并运行其中的类方法...

    关于JAVA内存泄漏问题注意事项

    以下是一些关于Java内存泄漏的注意事项和相关知识点: 1. **理解可达性和无用性**:内存泄漏在Java中发生时,通常是由于某些对象尽管不再使用,但仍然可以通过对象引用图到达,这使得垃圾收集器无法识别它们为无用...

    java源码包4

     Java局域网通信——飞鸽传书源代码,大家都知道VB版、VC版还有Delphi版的飞鸽传书软件,但是Java版的确实不多,因此这个Java文件传输实例不可错过,Java网络编程技能的提升很有帮助。 Java聊天程序,包括服务端和...

    java 例题 java 例题java 例题java 例题java 例题

    例如,你可能会遇到关于变量声明和初始化的例题,这会涉及基本数据类型(如int、double、boolean)和引用数据类型(如String、类实例)。通过这些例题,你可以学习如何声明变量,如何给变量赋值,以及理解不同类型...

    java源码包3

     Java局域网通信——飞鸽传书源代码,大家都知道VB版、VC版还有Delphi版的飞鸽传书软件,但是Java版的确实不多,因此这个Java文件传输实例不可错过,Java网络编程技能的提升很有帮助。 Java聊天程序,包括服务端和...

    JAVA上百实例源码以及开源项目

     Java局域网通信——飞鸽传书源代码,大家都知道VB版、VC版还有Delphi版的飞鸽传书软件,但是Java版的确实不多,因此这个Java文件传输实例不可错过,Java网络编程技能的提升很有帮助。 Java聊天程序,包括服务端和...

    java您所不知道的五件事--java对象序列化

    您觉得自己懂 Java 编程?事实上,大多数程序员对于 Java 平台都是浅尝则止,只学习了足以完成手头上任务的知识而已。在本 系列 中,Ted Neward 深入挖掘 Java 平台的核心功能,揭示一些鲜为人知的事实,帮助您解决...

    JAVA上百实例源码以及开源项目源代码

     Java局域网通信——飞鸽传书源代码,大家都知道VB版、VC版还有Delphi版的飞鸽传书软件,但是Java版的确实不多,因此这个Java文件传输实例不可错过,Java网络编程技能的提升很有帮助。 Java聊天程序,包括服务端和...

    jdk,用于java开发的系统的开发包

    3. **配置Eclipse**:在Eclipse的“Window” -> “Preferences” -> “Java” -> “Installed JREs”中添加JDK的路径,这样Eclipse就知道在哪里找到编译和运行Java程序所需的工具。 4. **验证设置**:在Eclipse中...

Global site tag (gtag.js) - Google Analytics