java四种引用_Java中四种引用

Java内存管理包括内存分配和内存回收。

内存分配:程序员通过new对象,JVM会自动为该对象分配内存。

内存回收:Java在JVM虚拟机上增加了垃圾回收(Garbage Collection)机制,用以在合适的时间触发垃圾回收,将不需要的内存空间回收释放,避免无限制的内存增长导致的OOM.

其实GC时主要看这个对象是否有引用指向该对象。按照这种引用的强弱的关系, 从JDK1.2版本开始,把对象的引用分为四种级别,从而使程序能更加灵活的控制对象的生命周期。这四种级别由高到低依次为:强引用、软引用、弱引用和虚引用。

四种引用

强引用(StrongReference)

是指创建一个对象并把这个对象赋给一个引用变量。比如Object tv = new Object();

强引用有引用变量指向时永远不会被垃圾回收,JVM宁愿抛出OutOfMemory错误也不会回收这种对象。

如果程序确实不在用到某个强引用变量,通常可以手动将这个引用指向赋值为null。比如常见的集合中claer()方法。下面这段代码就是ArrayList的clear()

/**

* Removes all of the elements from this list. The list will

* be empty after this call returns.

*/

public void clear() {

modCount++;

// clear to let GC do its work

for (int i = 0; i < size; i++)

elementData[i] = null;

size = 0;

}

软引用(SoftReference)

SoftReference softRef = new SoftReference<>(T t); 这样就可以把一个对象变成软引用

然后通过softRef.get()就能获得这个对象

只有在内存空间不足时,才会被回收的对象;使用的时候记得判空。

可用来实现内存敏感的高速缓存,比如网页缓存、图片缓存等;也能避免内存泄露,但在Android中不建议使用软引用。

弱引用(WeakReference)

WeakReference weakRef = new WeakReference<>(T t); 这样就可以把一个对象变成软引用

然后通过weakRef.get()就能获得这个对象

在 GC 时,一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存;使用的时候记得判空。

虚引用(PhantomReferece)

顾名思义,就是形同虚设,与其他几种引用都不同,虚引用并不会决定对象的生命周期。

任何时候都可以被GC回收,引用是最弱的。

ReferenceQueue queue = new ReferenceQueue ();

PhantomReference pr = new PhantomReference (object, queue);

由于引用关系最弱,并且源码中的get方法直接返回null,所以必须配合ReferenceQueue使用

public T get() {

return null;

}

Q:Android中为什么不推荐使用软引用(SoftReference)?

Avoid Soft References for Caching

In practice, soft references are inefficient for caching. The runtime doesn't have enough information on which references to clear and which to keep. Most fatally, it doesn't know what to do when given the choice between clearing a soft reference and growing the heap.

在实践中,软引用(soft references)在缓存中是低效的,因为runtime并没有足够的信息来判别应该清除或者保留哪个 SoftReference(持有的对象),更无法判定当 App 要求更多内存的时候,是应该清除 SoftReference,还是增大 App 的Heap。

The lack of information on the value to your application of each reference limits the usefulness of soft references. References that are cleared too early cause unnecessary work; those that are cleared too late waste memory.

你的程序的引用的信息的缺失导致软引用用处的局限性。过早清除的引用会导致无用功,太晚清除又会浪费内存。

Most applications should use an android.util.LruCache instead of soft references. LruCache has an effective eviction policy and lets the user tune how much memory is allotted.

大多数程序应该使用android.util.LruCache来替代软引用,LruCache有着更高效的回收策略,并让用户协调要分配多少内存。

在正常的 JVM中,只要不触发 OOM(达到系统内存上限或者到达 JVM 设定的内存上限),JVM 就应该毫不留情的增大 Heap 来维持应用的正常运行。 而没有必要考虑是先清理SoftReference,还是增大 Heap 。

Android Runtime与 JVM 不一样的是:用户 App 通常没有权限来设定自己的最大可用内存,这个是由系统控制的, 单个 App 使用的最大内存容量是固定的 Runtime.getRuntime().maxMemory()

Q:如果一个对象同时有强引用和弱引用与之关联,那GC的时候会回收吗?

伪代码

T t = new T();

WeakReference tRef = new WeakReference<>(t);

很显然GC的时候这个t不仅有弱引用还有强引用关联,此时是不会回收的。

Q: 既然虚引用形同虚设,那么它有什么作用?

网上找这样的描述:

Use Cases

There’re two common use-cases they are used for.

The first technique is to determine when an object was removed from the memory which helps to schedule memory-sensitive tasks. For example, we can wait for a large object to be removed before loading another one.

The second practice is to avoid using the finalize method and improve the finalization process.

第一个就是能够知道这个对象回收时机,能在对象被GC时收到系统通知

第二个就是避免使用finalize

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值