Java的RAM增加,尽管Heap保持不变?

21 浏览
0 Comments

Java的RAM增加,尽管Heap保持不变?

在我的应用程序中,我正在将文档上传到服务器,并对其进行一些分析。今天,我使用jconsole.exe和堆转储来分析我的应用程序,试图找出是否存在内存问题/内存泄漏。由于应用程序在运行时内存占用非常高,我认为可能存在内存泄漏问题。通过观察jconsole中的堆/代码缓存/perm gen等内存,我看到了以下情况,这让我感到惊讶:\n如右侧的jconsole中所示,进行相关分析工作时堆内存增长,但工作结束后又会恢复到正常大小。在左侧可以看到部署该应用程序的服务器上的\"htop\"。问题就在这里:尽管堆的行为正常,并且垃圾收集器似乎也在正常运行,但内存使用量非常高,接近3.2GB。\n这真的让我感到困惑。我在考虑是否与我的Java VM堆栈有关?我进行了一些研究,发现VM堆栈被描述为只有几兆字节(甚至只有几KB)的小内存。\n我的技术背景:\n- 应用程序运行在glassfish v.3.1.2上\n- 数据库运行在MySQL上\n- 使用Hibernate作为ORM框架\n- Java版本是1.7.0_04\n- 使用VAADIN实现\n- MySQL数据库和glassfish是该服务器上唯一运行的内容\n- 在分析过程中,我使用JAXB构建XML-DOM样式的文档,并将其保存在数据库中\n- 上传的文档可以是.txt或.pdf文件\n- 操作系统是Linux\n解决方案?\n你们有任何想法,为什么会出现这种情况,我应该怎么解决它吗?我真的很惊讶,因为我以为内存问题是由内存泄漏引起的堆内存暴增。但现在,堆不是问题,问题是RAM不断增加,而堆保持在同一水平。我不知道该怎么解决它。\n感谢你们与我分享的每一个想法。\n编辑:也许我还应该指出,这种行为目前使我无法真正让其他人使用我的应用程序。当RAM已满且服务器不再响应时,我就束手无策了。\n编辑2:也许我还应该补充说明,每次成功的进一步分析后,这个RAM都会继续增加。

0
0 Comments

Java RAM增加的原因是JVM实现中使用内存的许多因素,而不仅仅是堆设置。堆设置通过“-Xmx”只控制Java堆,而不控制JVM使用的本机内存,该内存根据实现方式完全不同地被消耗。

从以下文章中可以了解到,堆和垃圾收集器使用无法控制的本机内存来维护内存管理系统中维护Java堆的状态。这些数据结构必须被分配以跟踪空闲存储并在收集垃圾时记录进展。这些数据结构的确切大小和特性因实现而异,但许多与堆的大小成比例。

而JIT编译器和javac一样使用本机内存。

字节码编译使用本机内存(就像静态编译器gcc需要内存运行一样),但JIT的输入(字节码)和输出(可执行代码)也必须存储在本机内存中。包含许多JIT编译方法的Java应用程序使用的本机内存比较小的应用程序更多。

此外,类加载器也使用本机内存。

Java应用程序由定义对象结构和方法逻辑的类组成。它们还使用Java运行时类库(如java.lang.String)的类,并且可能使用第三方库。这些类需要在使用时存储在内存中。类的存储方式因实现而异。

此外,线程也占用内存。

可以看出,Java堆不是JVM实现中消耗内存的唯一因素,不是所有内容都放在JVM堆中,而且堆占用的本机内存要比为管理和簿记指定的内存多得多。

此外,应用服务器往往具有在JVM之外运行的本机代码,但仍然显示为与控制应用服务器的进程相关联的内存。

可以看出Java RAM增加的原因是JVM实现中许多因素的综合影响,而解决方法是优化内存管理和垃圾收集,以及优化编译和类加载器的使用。

0