取消
显示结果 
搜索替代 
您的意思是: 
cancel
2534
查看次数
6
有帮助
2
评论
julianchen
Spotlight
Spotlight
引言:您是否碰到某个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://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种方法了。

评论
bo chen
Spotlight
Spotlight
假装看懂了!{:2_29:}
cisco_china
Spotlight
Spotlight
感谢大佬分享,支持一下
入门指南

使用上面的搜索栏输入关键字、短语或问题,搜索问题的答案。

我们希望您在这里的旅程尽可能顺利,因此这里有一些链接可以帮助您快速熟悉思科社区:









快捷链接