请选择 进入手机版 | 继续访问电脑版

设为首页 收藏本站
思科社区 关注
思科社区

  思科 CCO 登录
 找回密码
 立即注册

扫一扫,访问微社区

搜索
热搜: 邮件服务器
查看: 451|回复: 2

【原创】【小目标,一个“译”】+ 如何在您的Java应用中查找并修复内存泄漏 (1)

[复制链接]
发表于 2018-9-25 15:29:26 | 显示全部楼层 |阅读模式
引言:您是否碰到某个Java应用程序起初运行良好,经过一段时间后却缓慢下来了?或者它在处理少量文件时性能不错,文件量一旦增加就性能下降的情况呢?那么很可能您遇到了内存泄漏的问题。



您是否碰到某个Java应用程序起初运行良好,经过一段时间后却缓慢下来了?或者它在处理少量文件时性能不错,文件量一旦增加就性能下降的情况呢?那么很可能您遇到了内存泄漏的问题。

在应对内存泄漏时,如果有人问我:“你是否知道此事的前因后果和应对方法的?”那么,我就会做如下回答:

目标受众

尽管在一般情况下,本文中所介绍的方法是独立于IDE和操作系统的,但是我在此所用到的截图和说明仍然来自于Fedora Linux和带插件开发的Eclipse。

内存泄漏的症状

起初运行速度快,但随着时间的推移速度就慢下来了。比如说:

·        能够正常处理少量数据集,但应对大量数据集时出现严重的性能问题。
·         
·        在您的JVM中,旧版本(Old-Generation)内存的使用率持续增加。
·         
·        在您的JVM中,出现内存耗尽的跳转错误。
·         
·        无故自我崩溃。
·         
常见的内存泄漏

Java中的内存泄漏通常发生在您忘记关闭某个资源,或是某个对象的引用没能释放的时候。例如:

·        文件/文本缓冲区没被关闭。(请参见:https://git.eclipse.org/r/#/c/31313/中的案例)
·         
·        在equals()和hashcode()不被使用时,各种哈希映射的引用仍然保持激活的状态,例如:
·         
·        import java.util.Map;
·         
·        public class MemLeak {
·         
·        public final String key;
·         
·        public MemLeak(String key) {
·         
·            this.key = key;
·         
·        }
·         
·        public static void main(String args[]) {
·         
·            try {
·         
·              Map map = System.getProperties();
·         
·              for(;;) {
·         
·                 map.put(newMemLeak("key"), "value");
·         
·              }
·         
·            }catch(Exception e) {
·         
·                e.printStackTrace();
·         
·            }
·         
·          }
·         
·        }
·         

·        其他各种细节(请参见:https://www.toptal.com/java/hunting-memory-leaks-in-java#memleak
·         
·        那些引用了各种外部类的内部类所导致的泄漏。(可以将它们变成静态来避免,请参见:https://blogs.oracle.com/olaf/entry/memory_leaks_made_easy)。
·         
如何一次性修复它们?

这里提供两种方法。第一种是尝试“快速修复”。如果此法失败,那么您就必须往下尝试一条漫长的解决之路了。

1)快速修复:使用Eclipse内存泄漏的警告(去捕捉一些泄漏)。

2)手动禁用和启用您代码的各个部分,并使用VisualVM(Jconsole或Thermostat)之类的工具观察JVM的内存使用情况。

1)快速修复:Eclipse内存泄漏的警告/错误。

为了遵从JDK 1.5+的代码规范,Eclipse会向您“抛出”一些明显泄漏用例的警告和错误。更精确地说,任何使用了closable(如1.5后出现的outputStream)的对象,如果它的引用是被销毁而不是封闭的话,就会抛出一个警告。然而在Eclipse的各个项目中,其检漏功能并非总是被启用的。因此,为了事先打开它们,您可以到项目的设置里,按照下图所示进行开启:

此处Eclipse罗列出了各种内存泄漏:
然而,就算使用了Eclipse的此项功能,系统仍无法探测到所有的文件关闭与泄漏。尤其是在使用旧式(1.5之前)代码时,您很可能会因为它们在使用过程中仅仅只是“关闭”(closable)了,而遇到泄漏问题了。也有时候,文件在深度嵌套中被打开/关闭,也会导致Eclipse无法检测到。因此如果您碰到这种情况,就可能需要去尝试第2种方法了。


  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5
平均得分3 (1 评价)
发表于 2018-9-26 09:06:43 | 显示全部楼层
假装看懂了!
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5
平均得分0 (0 评价)
发表于 2018-10-1 10:12:09 | 显示全部楼层
感谢大佬分享,支持一下
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5
平均得分0 (0 评价)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver | 思科社区  

GMT+8, 2018-10-24 13:44 , Processed in 0.089039 second(s), 37 queries .

京ICP备09041801号-187

版权所有 :copyright:1992-2019 思科系统  重要声明 | 保密声明 | 隐私权政策 | 商标 |

快速回复 返回顶部 返回列表