当前位置: 首页 > news >正文

《Effective Java》解读第7条:消除过期的对象引用精华总结

文章目录

  • 第7条:消除过期的对象引用精华总结
    • 三种经典的内存泄漏场景与解决方案
    • 总结

第7条:消除过期的对象引用精华总结

核心思想:
不要过分依赖垃圾回收器(GC)。 虽然Java拥有自动内存管理,但如果程序无意中保留了对象的引用(即“过期的对象引用”),这些对象依然无法被回收,从而导致内存泄漏。
内存泄漏在Java中表现为:对象在逻辑上已不再使用,但由于被意外的引用所持有,导致GC无法回收它们。

三种经典的内存泄漏场景与解决方案

  1. 类自己管理内存(最常见、最隐蔽)

场景:利用数组实现栈:

// Can you spot the "memory leak"?
public class Stack {private Object[] elements;private int size = 0;private static final int DEFAULT_INITIAL_CAPACITY = 16;public Stack() {elements = new Object[DEFAULT_INITIAL_CAPACITY];}public void push(Object e) {ensureCapacity();elements[size++] = e;}public Object pop() {if (size == 0)throw new EmptyStackException();return elements[--size];}/*** Ensure space for at least one more element, roughly* doubling the capacity each time the array needs to grow.*/private void ensureCapacity() {if (elements.length == size)elements = Arrays.copyOf(elements, 2 * size + 1);}
}

对于栈而言,elements数组中index >= size的部分是“有效元素”,而index < size的部分是“过期区域”。栈内部知道这些数据已无效,但GC不知道,只要数组还在,这部分引用指向的对象就永远不会被回收。

解决方案: 一旦对象引用不再需要,立即手动将其设置为null。

这种做法不应成为常态。最佳实践是让对象在其作用域结束时自然消亡。 只有在类自己管理内存(明确知道哪些引用已过期)时,才应该使用这种手动清空的方式。

  1. 缓存

场景:将对象放入缓存后,很容易忘记它们,从而使其长期留在内存中。

解决方法:
使用弱引用(WeakHashMap): 如果你要实现一个缓存,只要缓存项在外部没有其他强引用,就允许GC回收它们,那么WeakHashMap是理想选择。当GC运行时,这些条目会被自动清理。

后台清理: 对于更复杂的缓存,可以使用ScheduledThreadPoolExecutor或类似Caffeine、Guava Cache这样的缓存库,通过定时任务或基于访问频率等策略来定期清理过期条目。

  1. 监听器和其他回调

场景: 在API中注册了监听器或回调,但没有显式地取消注册。
如果客户端注册了回调却没有注销,那么回调对象(通常持有其外部类的引用)会一直被API持有,导致该客户端及其相关对象都无法被回收。

解决方案:
显式注销: 提供并鼓励使用unregister或removeListener方法。
使用弱引用: 仅保存监听器的弱引用(如WeakReference),这样当监听器对象没有其他强引用时,GC可以回收它,避免内存泄漏。

总结

  1. 警惕“内存管理器”角色: 只要一个类自己管理内存(如自定义的集合、对象池),你就应该警惕内存泄漏的可能性。
  2. null引用是“最后手段”: 不要在所有地方都滥用null。它应该作为一种明确的信号,表明“这个引用指向的对象我已明确不再需要,请GC可以回收它”。在绝大多数情况下,让变量自然超出作用域是更清晰、更推荐的做法。
  3. 优先使用现有工具: 对于缓存,优先考虑使用成熟的库(如Caffeine、Guava Cache),它们已经内置了强大的内存管理策略。
  4. 代码审查与静态分析: 内存泄漏通常难以通过单元测试发现,但在代码审查中应重点关注上述几种场景。同时,可以使用如FindBugs、SpotBugs、SonarQube等静态分析工具来帮助检测潜在的内存泄漏问题。
  5. 核心思维模式: 编程时要有“引用管理”的意识。不仅要考虑一个对象何时被使用,更要考虑它何时应该被“释放”。不要因为有了GC就高枕无忧。
http://www.dtcms.com/a/570624.html

相关文章:

  • 做网站 要学 什么语言网架公司和网架加工厂的区别
  • 环保工程东莞网站建设搭建商城哪家好点
  • x86架构下docker部署freeswitch
  • 金融网站设计方案百度发布信息怎么弄
  • 单人做网站asp.net企业网站建设
  • 如何网站增加域名做宠物服务的相关网站
  • 建材网站建设功能方案jquery 的网站模板
  • Similarity Between Binary Vectors|二元向量的相似性
  • [CSP-J2025入门级T3]异或和
  • 网站制作器手机版下载wordpress d
  • 广东省住房和城乡建设局网站首页炫酷企业网站
  • C++:用哈希表封装unordered_map,unordered_set(代码版)
  • 安徽建设工程信息网站做地方网站数据哪里来
  • 门户网站开发请示50个单页面网站设计欣赏(2)
  • 代码随想录训练营打卡Day36| 动态规划part04
  • HTB-Alert靶场 | 低难度Linux提权实战:漏洞链利用(XSS→文件读取→定时任务)详解
  • 我想做个网站推广怎么做网页制作与设计考的在哪查房
  • o2o商城网站建设方案怎么建网站
  • 从0开始学算法——第一天(认识算法)
  • 节点小宝4.0相册备份功能升级:技术优化与用户体验提升
  • 福州网站建设询q479185700上快成都大型网站建设公司排名
  • 第22课:行业实战:构建高质量技术文档智能支持系统
  • 网站关闭与域名备案app下载官网入口
  • 湛江网站建设方案外包1+手机官网首页
  • 4、foc控制系统——统一架构设计
  • QuickEsView
  • 积极做好门户网站建设工作住房城乡建设部举报网站
  • 企业网站会涉及到的版权问题网络服务投诉
  • AI 重塑招聘格局,传统招聘模式面临转型挑战
  • 网站帮助文档怎么写省财政厅门户网站三基建设