绑定完请刷新页面
取消
刷新

分享好友

×
取消 复制
怎么用弱引用实现内存泄漏检测
2017-06-04 10:29:53

在Java中,引用分为强引用、软引用、弱引用和虚引用四种。

  • 强引用,代码中普遍存在的形式,例如常见的普通类new出对象后的引用。GC不会回收强引用的对象。
  • 软引用,软引用对象会在内存溢出异常之前进行回收,也就是说在内存富裕的情况下GC不回收软引用。它可通过SoftReference类实现。
  • 弱引用,弱引用对象会在下一次GC时被回收,也就是说不管内存富不富裕,当GC时都会回收弱引用。它可通过WeakReference类实现。
  • 虚引用,虚引用不会改变对象的生存时间,它只是让对象在被GC时能收到一个系统通知。

了解了所有引用类型后看下如何基于弱引用对程序进行内存泄漏检测。

假如在你的程序中有某类的对象很可能会造成内存泄漏,姑且称为MaybeMemoryLeak类。内存泄漏就是虚拟机在做垃圾回收时某些“垃圾”由于某些原因而导致无法回收,每次实例化出来的对象都无法回收,终导致内存爆了。也就是如果某些MaybeMemoryLeak应该被回收的对象无法回收,就会导致内存泄漏。

如果无法避免内存泄漏的可能性,那么如何检测内存泄漏现象呢?

这里就要用到上面所说的弱引用,它能很好判断MaybeMemoryLeak有没有被GC回收,被弱引用关联的对象只能生存到下一次垃圾回收发生之前,即如果某MaybeMemoryLeak对象只被某弱引用关联,则它会在下次垃圾回收时被回收,但如果MaybeMemoryLeak对象除了被弱引用关联外还被其他对象强引用,那么MaybeMemoryLeak对象是不会被回收的,根据这些条件就可以判断是否有MaybeMemoryLeak内存泄漏了。

在实际的实现中可以通过WeakHashMap来实现弱引用,只需将MaybeMemoryLeak对象put到WeakHashMap中,例如weakMap.put(“a”,maybeMemoryLeak),当maybeMemoryLeak及其包含的元素没有被其它任何类加载器中的元素引用到时,JVM发生垃圾回收时则会把maybeMemoryLeak对象回收,否则就将一直回收不了。

这里使用一个WeakHashMap用于追踪MaybeMemoryLeak对象,在查找内存泄漏之前要先强制调用System.gc();进行一次垃圾回收,保证没问题的MaybeMemoryLeak对象都被回收掉,这时可以查看WeakHashMap对象还存在哪些MaybeMemoryLeak对象,如果存在某些“垃圾”MaybeMemoryLeak对象,则属于内存泄漏。

====广告时间,可直接跳过====

鄙人的新书《Tomcat内核设计剖析》已经在京东预售了,有需要的朋友可以到 item.jd.com/12185360.ht… 进行预定。感谢各位朋友。

=========================

欢迎关注:

这里写图片描述

分享好友

分享这个小栈给你的朋友们,一起进步吧。

远洋号
创建时间:2020-05-19 15:46:16
《图解数据结构与算法》《Tomcat内核设计剖析》书籍作者,公众号:《远洋号》,笔名:seaboat,擅长工程算法、人工智能算法、自然语言处理、架构、分布式、高并发、大数据、搜索引擎等方面的技术,大多数编程语言都会使用但更擅长Java、Python、C++。平时喜欢看书、写作、运动,擅长的项目有篮球、跑步、游泳、健身、羽毛球。崇尚开源,崇尚技术自由,更崇尚思想自由。
展开
订阅须知

• 所有用户可根据关注领域订阅专区或所有专区

• 付费订阅:虚拟交易,一经交易不退款;若特殊情况,可3日内客服咨询

• 专区发布评论属默认订阅所评论专区(除付费小栈外)

栈主、嘉宾

查看更多
  • seaboat
    栈主

小栈成员

查看更多
  • 小雨滴
  • Tester9456
  • 栈栈
  • dkl187788
戳我,来吐槽~