4年前 (2021-01-22)  jvm |   抢沙发  578 
文章评分 0 次,平均分 0.0

Java内存泄漏可能是致命的,而且很难排除故障。您是否属于定期(每周、每天或更频繁)重新启动应用程序服务器的商店之一?真可怜,不是吗?等等,我们在服务器上拥有128MB内存的日子一去不复返了。我们在服务器上有好几十亿字节的内存,不是吗?为什么我们还遇到内存问题?问得好。但可悲的是,有几个原因可以解释为什么内存泄漏不会消失。你所能做的就是做好准备。这就是本文的主题。让我们深入了解有关Java内存泄漏的10件事情。

1. Java堆内存泄漏不同于本机内存泄漏

Java堆是应用程序创建的对象所在的位置。最大堆由启动应用程序的Java命令行的–Xmx标志确定。如果你写的代码泄露了内存,那么它就会爆炸。

本机内存在Java堆之外,但仍在总“进程大小”之内。这是底层驱动程序(如文件系统句柄、线程等)消耗内存的地方。如果您使用的第三方库使用的是本机内存,并且存在泄漏,那么它就会在这里爆炸。

在本文中,每当我谈到内存泄漏时,我都会提到Java堆(而不是本机内存)

总进程大小=Java堆+本机内存

2. 内存泄漏将是显而易见的

内存泄漏将非常明显。但你需要某种监控工具。看看下面一个经典的内存泄漏

一周内的堆利用率:

关于Java内存泄漏,你需要知道的十件事

您看到了堆利用率是如何持续下去的,但从来没有随着时间的推移而真正下降吗?一个健康的应用程序在堆使用率图上会有锯齿状的模式(使用率会随着时间的推移而上升,但是GC会使其下降,并且这个周期会重复)。

虽然内存泄漏很明显,但不幸的是,内存泄漏的根本原因并不明显。见下文。

3. 你可以采取堆转储,看看是什么填补了堆

如果您想知道是什么填充了堆,可以进行堆转储生成dump文件并进行分析。这不是一个直截了当的过程,而且很费时。但这是深入了解应用程序的一个非常好的方法。应用服务器可以提供命令/脚本来执行堆转储。但是下面的命令适用于任何Java进程

jmap –dump:format=b,file=<dump file path> <pid>

注意,进行堆转储将暂停JVM。如果堆很大(4gb+),转储堆可能需要几秒钟。所以,在生产中运行之前,请确保您可以接受这一点。

我最喜欢的分析堆转储的工具是Eclipse内存分析器。它速度快,用途广。我有一篇关于如何使用Eclipse内存分析器的单独文章:如何使用Eclipse内存分析工具定位内存泄露

关于Java内存泄漏,你需要知道的十件事

4. Java内存泄漏的常见原因1

“异常”后不清理。这是什么意思?假设在运行时遇到意外的异常(可能是远程服务超时)。当函数由于异常而中断时,您必须确保清除正在执行的任何操作。例如,如果有一个DB事务正在进行,那么必须关闭“try catch”的“finally”块中的所有事务。如果异常重复出现,这一点尤为重要。许多管理员和开发人员不关心重复“无害”的异常。“例外”没有什么无害的。一定要正确处理。

5. Java内存泄漏的常见原因2

处理内存中的大型结果集。你不想在一次通话中带来数百万张唱片。这看起来很明显,但我仍然看到开发人员低估了产品中结果集的大小,最终填满了JVM堆。使用“分页”或“延迟加载”等技术

6. OutOfMemoryError并不一定意味着内存泄漏

不要直接将“OutOfMemoryError”等同于内存泄漏。事实上,您可以有内存泄漏,而没有任何错误。为什么会发生“内存不足”有几个原因。例如,它可能是由于“碎片”而发生的(每当Jvm分配内存时,它必须是连续的内存块)。如果“PermGen”已满(堆中存储类对象和内部字符串的区域),也会发生“OutOfMemoryError”。

7. 为了成功定位内存泄漏,您需要对应用程序有一些了解

作为一个管理员,你可以用你所有的工具挖掘你想要的一切。但是一点特定于应用程序的知识将大大有助于找到根本原因。确保应用程序的开发人员参与了故障排除过程。

8. 堆直方图可以用来缩小内存泄漏

堆直方图可以作为内存泄漏故障排除的起点。

Jmap –histo <pid>

将输出重定向到文件,因为输出可能相当长。输出将包含内存中每个类的类名、实例数和大小。每隔几分钟做几张直方图,注意任何趋势。

9. 有一些操作系统工具可以跟踪本机内存泄漏

要解决本机内存泄漏问题,您需要使用操作系统工具。在Linux上,试试jemalloc。在solaris上,请尝试watchmalloc。在Windows上查找/Md和/Mdd编译器选项。

10. 有强大的第三方配置文件,你可以使用

如果你真的对内存泄漏很认真(为什么不呢?),您应该使用第三方工具,如Quest Jprobe和Borland Optimizeit。它们从Java内存中挖掘出了活的白昼,并清楚地向您展示了正在发生的事情。请注意,分析Java应用程序以跟踪内存泄漏是一个耗时且迭代的过程。但它确实有用。

 

除特别注明外,本站所有文章均为老K的Java博客原创,转载请注明出处来自https://javakk.com/1352.html

关于

发表评论

表情 格式

暂无评论

登录

忘记密码 ?

切换登录

注册