在我的应用程序中,我将文档上传到服务器,然后对其进行一些分析。
今天我使用jconsole.exe和堆转储分析了我的应用程序,因为我试图找出我是否有内存问题/内存泄漏。我认为我可能会受到影响,因为我的应用程序在应用程序运行时在RAM上非常增长。
当我在一些运行后用jconsole观察堆/ codecache / perm gen等内存时,我很惊讶,因为我看到了以下内容:
图片链接:https://www7.pic-upload.de/13.06.12/murk9qrka8al.png
正如您在右侧的jconsole中看到的那样,当我正在进行与分析相关的事情时,堆正在增加,但是当工作结束时,它也会再次减少到正常大小。在左侧,您可以看到部署应用程序的服务器的“htop”。它是:RAM是,虽然堆正常运行,但垃圾收集器似乎运行正常,难以置信高达近2,2gb。
现在这让我很困惑。我在想我的java vm堆栈是否可以对此做些什么?我做了一些研究,我发现了关于vm堆栈的内容,它只是一个只有几兆字节(甚至只有kb)的小内存。
我的技术背景:
解决方案吗
你有什么想法为什么会发生这种情况以及我能做些什么来修复它?我现在真的很惊讶,因为我认为内存问题来自内存泄漏导致堆爆炸。但是现在,堆不是问题。当堆停留在同一级别时,RAM越来越高。我不知道如何解决它。
感谢您与我分享的每一个想法。
编辑:也许我还应该说明,这种行为目前让我无法真正让其他人使用我的应用程序。当RAM已满并且服务器不再响应时我就出去了。
编辑2:也许我还应该补充一点,在每次成功进一步分析后,这个RAM会不断增加。
答案 0 :(得分:1)
通过-Xmx
的堆设置仅控制Java堆,它不控制JVM对本机内存的消耗,根据实现情况完全不同地消耗它。
来自以下文章Thanks for the Memory ( Understanding How the JVM uses Native Memory on Windows and Linux )
维护堆和垃圾收集器使用您无法控制的本机内存。
需要更多的本机内存来维护状态 内存管理系统维护Java堆。数据结构 必须分配以跟踪免费存储并记录进度 收集垃圾。这些数据结构的确切大小和性质 随实施而变化,但许多与大小成正比 堆。
并且JIT编译器使用本机内存,就像javac
字节码编译使用本机内存(与静态内存相同) 编译器如gcc需要内存运行),但两者都是输入( 字节码)和JIT的输出(可执行代码)也必须 存储在本机内存中。包含许多的Java应用程序 JIT编译的方法比较小的应用程序使用更多的本机内存。
然后你有使用本机内存的类加载器
Java应用程序由定义对象结构的类组成 和方法逻辑。它们还使用Java运行时类中的类 库(如java.lang.String)并可能使用第三方 库。只要这些类需要存储在内存中 他们正在被使用。如何存储类因实现而异。
我甚至不会开始引用关于Threads的部分,我想你明白了 Java堆不是唯一在JVM实现中消耗内存的东西,而不是所有东西 进入JVM堆,并且堆占用了您指定的更多本机内存 管理和簿记。
App Server多次具有在JVM外部运行的本机代码,但仍然显示为与控制应用服务器的进程关联的内存。