- 浏览: 316271 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
u011076522:
写的确实不错,总结的很好,内容大都属实
C/C++内存分配方式 -
水晶魔方:
...
联合编译工具推荐IncrediBuild -
caiwb1990:
又看了一遍~ 越看越清晰~
C/C++内存分配方式 -
caiwb1990:
每次准备面试的时候来瞅瞅。timer_yin 写道好文,正好补 ...
TCP/IP、Http、Socket的区别【转】 -
caiwb1990:
互相学习~kongxuan 写道这个不错,用简单的话将事情讲明 ...
TCP/IP、Http、Socket的区别【转】
Java中的几种引用类型还是蛮重要的,需要好好理解一下~
StrongReference、 SoftReference、 WeakReference 以及 PhantomReference 是Java中的4种引用类型,我们来分别看看
1. Strong Reference
StrongReference 是 Java 的默认引用实现, 它会尽可能长时间的存活于 JVM 内, 当没有任何对象指向它时 GC 执行后将会被回收
2. WeakReference & WeakHashMap
WeakReference, 顾名思义, 是一个弱引用, 当所引用的对象在 JVM 内不再有强引用时, GC 后 weak reference 将会被自动回收
WeakHashMap 使用 WeakReference 作为 key, 一旦没有指向 key 的强引用, WeakHashMap 在 GC 后将自动删除相关的 entry
3. SoftReference
SoftReference 于 WeakReference 的特性基本一致, 最大的区别在于 SoftReference 会尽可能长的保留引用直到 JVM 内存不足时才会被回收(虚拟机保证), 这一特性使得 SoftReference 非常适合缓存应用
4. PhantomReference
最关键的来了, Phantom Reference(幽灵引用) 与 WeakReference 和 SoftReference 有很大的不同, 因为它的 get() 方法永远返回 null, 这也正是它名字的由来
诸位可能要问, 一个永远返回 null 的 reference 要来何用, 请注意构造 PhantomReference 时的第二个参数 ReferenceQueue(事实上 WeakReference & SoftReference 也可以有这个参数),
PhantomReference 唯一的用处就是跟踪 referent 何时被 enqueue 到 ReferenceQueue 中.
5. RererenceQueue
当一个 WeakReference 开始返回 null 时, 它所指向的对象已经准备被回收, 这时可以做一些合适的清理工作. 将一个 ReferenceQueue 传给一个 Reference 的构造函数, 当对象被回收时, 虚拟机会自动将这个对象插入到 ReferenceQueue 中, WeakHashMap 就是利用 ReferenceQueue 来清除 key 已经没有强引用的 entries.
6. PhantomReference vs WeakReference
PhantomReference 有两个好处, 其一, 它可以让我们准确地知道对象何时被从内存中删除, 这个特性可以被用于一些特殊的需求中(例如 Distributed GC, XWork 和 google-guice 中也使用 PhantomReference 做了一些清理性工作).
其二, 它可以避免 finalization 带来的一些根本性问题, 上文提到 PhantomReference 的唯一作用就是跟踪 referent 何时被 enqueue 到 ReferenceQueue 中, 但是 WeakReference 也有对应的功能, 两者的区别到底在哪呢 ?
这就要说到 Object 的 finalize 方法, 此方法将在 gc 执行前被调用, 如果某个对象重载了 finalize 方法并故意在方法内创建本身的强引用, 这将导致这一轮的 GC 无法回收这个对象并有可能
引起任意次 GC, 最后的结果就是明明 JVM 内有很多 Garbage 却 OutOfMemory, 使用 PhantomReference 就可以避免这个问题, 因为 PhantomReference 是在 finalize 方法执行后回收的,也就意味着此时已经不可能拿到原来的引用, 也就不会出现上述问题, 当然这是一个很极端的例子, 一般不会出现.
7. 小结
一般的应用程序不会涉及到 Reference 编程, 但是了解这些知识会对理解 GC 的工作原理以及性能调优有一定帮助, 在实现一些基础性设施比如缓存时也可能会用到, 希望本文能有所帮助.
StrongReference、 SoftReference、 WeakReference 以及 PhantomReference 是Java中的4种引用类型,我们来分别看看
1. Strong Reference
StrongReference 是 Java 的默认引用实现, 它会尽可能长时间的存活于 JVM 内, 当没有任何对象指向它时 GC 执行后将会被回收
@Test public void strongReference() { Object referent = new Object(); /** * 通过赋值创建 StrongReference */ Object strongReference = referent; assertSame(referent, strongReference); referent = null; System.gc(); /** * StrongReference 在 GC 后不会被回收 */ assertNotNull(strongReference); }
2. WeakReference & WeakHashMap
WeakReference, 顾名思义, 是一个弱引用, 当所引用的对象在 JVM 内不再有强引用时, GC 后 weak reference 将会被自动回收
@Test public void weakReference() { Object referent = new Object(); WeakReference<Object> weakRerference = new WeakReference<Object>(referent); assertSame(referent, weakRerference.get()); referent = null; System.gc(); /** * 一旦没有指向 referent 的强引用, weak reference 在 GC 后会被自动回收 */ assertNull(weakRerference.get()); }
WeakHashMap 使用 WeakReference 作为 key, 一旦没有指向 key 的强引用, WeakHashMap 在 GC 后将自动删除相关的 entry
@Test public void weakHashMap() throws InterruptedException { Map<Object, Object> weakHashMap = new WeakHashMap<Object, Object>(); Object key = new Object(); Object value = new Object(); weakHashMap.put(key, value); assertTrue(weakHashMap.containsValue(value)); key = null; System.gc(); /** * 等待无效 entries 进入 ReferenceQueue 以便下一次调用 getTable 时被清理 */ Thread.sleep(1000); /** * 一旦没有指向 key 的强引用, WeakHashMap 在 GC 后将自动删除相关的 entry */ assertFalse(weakHashMap.containsValue(value)); }
3. SoftReference
SoftReference 于 WeakReference 的特性基本一致, 最大的区别在于 SoftReference 会尽可能长的保留引用直到 JVM 内存不足时才会被回收(虚拟机保证), 这一特性使得 SoftReference 非常适合缓存应用
@Test public void softReference() { Object referent = new Object(); SoftReference<Object> softRerference = new SoftReference<Object>(referent); assertNotNull(softRerference.get()); referent = null; System.gc(); /** * soft references 只有在 jvm OutOfMemory 之前才会被回收, 所以它非常适合缓存应用 */ assertNotNull(softRerference.get()); }
4. PhantomReference
最关键的来了, Phantom Reference(幽灵引用) 与 WeakReference 和 SoftReference 有很大的不同, 因为它的 get() 方法永远返回 null, 这也正是它名字的由来
@Test public void phantomReferenceAlwaysNull() { Object referent = new Object(); PhantomReference<Object> phantomReference = new PhantomReference<Object>(referent, new ReferenceQueue<Object>()); /** * phantom reference 的 get 方法永远返回 null */ assertNull(phantomReference.get()); }
诸位可能要问, 一个永远返回 null 的 reference 要来何用, 请注意构造 PhantomReference 时的第二个参数 ReferenceQueue(事实上 WeakReference & SoftReference 也可以有这个参数),
PhantomReference 唯一的用处就是跟踪 referent 何时被 enqueue 到 ReferenceQueue 中.
5. RererenceQueue
当一个 WeakReference 开始返回 null 时, 它所指向的对象已经准备被回收, 这时可以做一些合适的清理工作. 将一个 ReferenceQueue 传给一个 Reference 的构造函数, 当对象被回收时, 虚拟机会自动将这个对象插入到 ReferenceQueue 中, WeakHashMap 就是利用 ReferenceQueue 来清除 key 已经没有强引用的 entries.
@Test public void referenceQueue() throws InterruptedException { Object referent = new Object(); ReferenceQueue<Object> referenceQueue = new ReferenceQueue<Object>(); WeakReference<Object> weakReference = new WeakReference<Object>(referent, referenceQueue); assertFalse(weakReference.isEnqueued()); Reference<? extends Object> polled = referenceQueue.poll(); assertNull(polled); referent = null; System.gc(); assertTrue(weakReference.isEnqueued()); Reference<? extends Object> removed = referenceQueue.remove(); assertNotNull(removed); }
6. PhantomReference vs WeakReference
PhantomReference 有两个好处, 其一, 它可以让我们准确地知道对象何时被从内存中删除, 这个特性可以被用于一些特殊的需求中(例如 Distributed GC, XWork 和 google-guice 中也使用 PhantomReference 做了一些清理性工作).
其二, 它可以避免 finalization 带来的一些根本性问题, 上文提到 PhantomReference 的唯一作用就是跟踪 referent 何时被 enqueue 到 ReferenceQueue 中, 但是 WeakReference 也有对应的功能, 两者的区别到底在哪呢 ?
这就要说到 Object 的 finalize 方法, 此方法将在 gc 执行前被调用, 如果某个对象重载了 finalize 方法并故意在方法内创建本身的强引用, 这将导致这一轮的 GC 无法回收这个对象并有可能
引起任意次 GC, 最后的结果就是明明 JVM 内有很多 Garbage 却 OutOfMemory, 使用 PhantomReference 就可以避免这个问题, 因为 PhantomReference 是在 finalize 方法执行后回收的,也就意味着此时已经不可能拿到原来的引用, 也就不会出现上述问题, 当然这是一个很极端的例子, 一般不会出现.
7. 小结
一般的应用程序不会涉及到 Reference 编程, 但是了解这些知识会对理解 GC 的工作原理以及性能调优有一定帮助, 在实现一些基础性设施比如缓存时也可能会用到, 希望本文能有所帮助.
发表评论
-
ArrayList 和 LinkedList
2012-03-14 03:11 1752今天有人问这个,发现自己只是大概理解而且只会用了。该忘的竟然忘 ... -
Java总结-图形界面编程
2012-02-14 20:59 1378图形界面编程: java ... -
Java总结-正则表达式
2012-02-14 20:57 1131正则表达式: 专门用于操作字符串的规则。 将一 ... -
Java常用对象
2012-02-11 09:53 888java.lang.System: 该类中的方法都 ... -
集合总结
2012-02-11 09:51 1361Iterator:迭代器。 用来取出Collectio ... -
多线程总结
2012-02-10 10:20 1394多线程: 线程是进程中的一个控制单元。 一个进 ... -
异常总结
2012-02-10 10:18 1009异常: 自定义异常: 在java对一些常见的情况进 ... -
Java总结-面向对象进阶
2012-02-10 10:17 863接口: 它是一个特殊的抽象类。里面都是抽象方法。 ... -
Java总结-继承和抽象
2012-02-10 10:16 1233继承: 提高了代码 ... -
Java总结-构造和内部类
2012-02-10 10:15 963构造函数: 格式: 1,函数名和类名相同。 2 ... -
Java总结-面向对象初步
2012-02-09 14:53 968面向对象: 1,它是一种符合现实中人们思考习惯的一 ... -
Java总结-函数和数组
2012-02-09 14:50 3613函数: 特点: 1,程序中一段独立的小程序。 ... -
Java总结-流程控制
2012-02-09 14:47 1142程序的流程控制; 1 ... -
Java总结-基础
2012-02-09 14:43 953原来的Java笔记 整理了按天传上来~ java语言特性 ... -
IO操作流总结
2012-02-09 09:30 1305import java.io.*; /* ... -
Java排序汇总
2012-02-08 09:35 1221几种简单的排序的 Java 实现 代码注释非常详细~ im ... -
Java排序汇总
2012-02-07 10:48 22几种简单的排序的 Java 实现 代码注释非常详细~ im ... -
JFreeChart核心类库中的核心类的方法详解
2012-02-07 09:23 1403--核心类主要有: org.jfree.chart.JFre ... -
JFreeChart使用心得与例子
2012-02-07 09:22 1740一、JFreeChart的介绍与获 ... -
java多线程总结: 线程的两种创建方式及优劣比较
2011-11-23 10:26 11371、通过实现Runnable接口线程创建 (1).定义一个类 ...
相关推荐
Java垃圾收集(Garbage Collection, 简称GC)是Java编程中的一项重要特性,它自动管理内存,释放不再使用的对象,避免了程序员手动管理内存可能导致的内存泄露问题。本篇将深入探讨Java中的GC过程。 一、Java内存...
Java内存区域和垃圾收集(GC)机制是Java编程中至关重要的一部分,它关乎程序的性能、稳定性和资源管理。本文将深入探讨Java虚拟机(JVM)中的内存划分、垃圾收集的工作原理以及相关工具的使用。 1. **Java内存区域...
5. **避免内存泄漏**:定期检查代码中的内存泄漏问题,减少不必要的对象引用,从而减轻GC的压力。 #### 结论 深入了解Java GC的工作原理,并结合具体应用需求进行合理配置,是提升Java应用性能的重要手段。通过...
这篇文章将深入探讨Java中的垃圾收集机制,以及如何通过源码和工具来理解和分析GC的行为。 首先,垃圾收集是Java虚拟机(JVM)自动进行的一种内存管理方式,它的主要任务是识别并释放那些不再被程序使用的对象所...
在C++中,程序员需要手动进行内存分配和释放,而在Java中,GC自动执行这些任务,提高了开发效率并减少了因手动管理内存可能导致的错误。 GC的工作主要包含以下几个方面: 1. **判断垃圾对象**: - 引用计数法:每...
Java虚拟机(JVM)中的GC机制会定期检查堆内存中的对象,判断它们是否仍处于活动状态。如果某个对象不再被任何变量引用,即认为该对象已经“不可达”,GC就会回收这些对象所占用的内存空间。 **2.2 对象的分配与回收*...
### Java中的软引用、弱引用和虚引用详解 #### 一、引言 在Java开发过程中,特别是Android应用开发中,经常会遇到一个普遍的问题——内存溢出(OutOfMemory Error,简称OOM)。这个问题往往与如何有效地管理内存...
Java垃圾收集(GC)专题针对的是Java编程语言中内存管理机制的重要组成部分。Java自1996年推出以来,其最大的改进之一就是引入了受管内存。在Java之前,C和C++语言中的内存泄漏问题十分常见,这导致开发稳定和安全的...
Java垃圾回收GC机制是Java虚拟机中的一种自动内存管理机制,它可以提高Java程序的开发效率和稳定性。GC机制的实现基于分代收集算法,可以分为普通GC和全局GC两种类型。不同的GC算法有其优缺,选择合适的GC算法可以...
Java虚拟机(JVM)中的垃圾...总的来说,理解Java虚拟机中GC的基本原理,并掌握如何调整和优化GC,是提升Java应用性能的关键。开发者应关注GC的工作机制,以便更好地控制和管理内存,从而实现高效、稳定的应用程序。
Java垃圾回收(GC)机制是Java编程语言中的一个重要特性,它自动管理程序的内存空间,负责识别并清除不再使用的对象,以防止内存泄漏。本文将深入探讨Java GC的工作原理、类型、过程以及优化策略。 一、Java垃圾...
在Java编程语言中,垃圾回收(Garbage Collection, GC)是一项至关重要的机制,它自动管理内存,释放不再使用的对象,防止内存泄漏。本篇将深入探讨如何监控Java的垃圾回收,帮助开发者提升应用性能和稳定性。 Java...
Java的垃圾回收(GC)机制是其内存管理的核心部分,它自动检测并回收不再使用的对象,以避免内存泄漏和系统不稳定。GC的存在使得Java程序员无需手动管理内存,降低了程序出错的可能性。 GC的基本原理是基于对象的...
Java的垃圾收集机制(Garbage Collection, GC)是其虚拟机(JVM)的一个关键特性,它自动管理程序中的内存,避免了手动内存管理带来的低效和错误。GC的主要目标是回收不再使用的对象,以便释放内存空间并防止内存...
GC主要针对的是Java堆内存中的对象,这里的对象是由Java栈中的引用指向的。Java栈中每个线程都有一个独立的虚拟机栈,用于存储局部变量表、操作数栈、动态链接和方法出口等信息。当对象不再有任何引用链(GC Roots)...
Java 7 GC(垃圾回收)参数配置是Java虚拟机(JVM)调优的关键组成部分,它决定了垃圾回收的行为和性能表现。本文将详细介绍Java 7中常见的垃圾回收器和相应的JVM参数,帮助读者更好地理解和使用这些参数进行性能...