mirror of
https://github.com/sjsdfg/effective-java-3rd-chinese.git
synced 2025-03-24 08:10:32 +08:00
Update 07. 消除过期的对象引用.md
This commit is contained in:
parent
1bf3d24d66
commit
71c6044ccf
@ -1,6 +1,5 @@
|
||||
# 7. 消除过期的对象引用
|
||||
|
||||
---
|
||||
|
||||
如果你从使用手动内存管理的语言 (如 C 或 C++) 切换到像 Java 这样的带有垃圾收集机制的语言,那么作为程序员的工作就会变得容易多了,因为你的对象在使用完毕以后就自动回收了。当你第一次体验它的时候,它就像魔法一样。这很容易让人觉得你不需要考虑内存管理,但这并不完全正确。
|
||||
|
||||
@ -63,9 +62,9 @@ public Object pop() {
|
||||
|
||||
一般来说,**当一个类自己管理内存时,程序员应该警惕内存泄漏问题。** 每当一个元素被释放时,元素中包含的任何对象引用都应该被清除。
|
||||
|
||||
**另一个常见的内存泄漏来源是缓存。**一旦将对象引用放入缓存中,很容易忘记它的存在,并且在它变得无关紧要之后,仍然保留在缓存中。对于这个问题有几种解决方案。如果你正好想实现了一个缓存:只要在缓存之外存在对某个项(entry)的键(key)引用,那么这项就是明确有关联的,就可以用 `WeakHashMap` 来表示缓存;这些项在过期之后自动删除。记住,只有当缓存中某个项的生命周期是由外部引用到键(key)而不是值(value)决定时,`WeakHashMap` 才有用。
|
||||
**另一个常见的内存泄漏来源是缓存。** 一旦将对象引用放入缓存中,很容易忘记它的存在,并且在它变得无关紧要之后,仍然保留在缓存中。对于这个问题有几种解决方案。如果你正好想实现了一个缓存:只要在缓存之外存在对某个项(entry)的键(key)引用,那么这项就是明确有关联的,就可以用 `WeakHashMap` 来表示缓存;这些项在过期之后自动删除。记住,只有当缓存中某个项的生命周期是由外部引用到键(key)而不是值(value)决定时,`WeakHashMap` 才有用。
|
||||
|
||||
更常见的情况是,缓存项有用的生命周期不太明确,随着时间的推移一些项变得越来越没有价值。在这种情况下,缓存应该偶尔清理掉已经废弃的项。这可以通过一个后台线程 (也许是 `ScheduledThreadPoolExecutor`) 或将新的项添加到缓存时顺便清理。Link`此处输入代码`edHashMap 类使用它的 `removeEldestEntry` 方法实现了后一种方案。对于更复杂的缓存,可能直接需要使用 `java.lang.ref`。
|
||||
更常见的情况是,缓存项有用的生命周期不太明确,随着时间的推移一些项变得越来越没有价值。在这种情况下,缓存应该偶尔清理掉已经废弃的项。这可以通过一个后台线程 (也许是 `ScheduledThreadPoolExecutor`) 或将新的项添加到缓存时顺便清理。`LinkedHashMap` 类使用它的 `removeEldestEntry` 方法实现了后一种方案。对于更复杂的缓存,可能直接需要使用 `java.lang.ref`。
|
||||
|
||||
第三个常见的内存泄漏来源是监听器和其他回调。如果你实现了一个 API,其客户端注册回调,但是没有显式地撤销注册回调,除非采取一些操作,否则它们将会累积。确保回调是垃圾收集的一种方法是只存储弱引用(weak references),例如,仅将它们保存在 `WeakHashMap` 的键(key)中。
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user