Java RAM增加,但堆保持不变?

Java RAM增加,但堆保持不变?,java,glassfish,stack,heap,Java,Glassfish,Stack,Heap,可能重复: 在我的应用程序中,我将文档上传到服务器,服务器对其进行分析 今天,我使用jconsole.exe和堆转储分析了我的应用程序,试图找出是否存在内存问题/内存泄漏。我想我可能会遇到这样的问题,因为在应用程序运行时,我的应用程序在RAM上增长得非常快 运行了几次之后,当我用jconsole观看heap/codecache/perm gen等内存时,我惊讶地看到以下内容: 图片链接: 正如您在右侧的jconsole中看到的,当我分析相关内容时,堆正在增加,但当工作结束时,堆也会再次减小到

可能重复:

在我的应用程序中,我将文档上传到服务器,服务器对其进行分析

今天,我使用jconsole.exe和堆转储分析了我的应用程序,试图找出是否存在内存问题/内存泄漏。我想我可能会遇到这样的问题,因为在应用程序运行时,我的应用程序在RAM上增长得非常快

运行了几次之后,当我用jconsole观看heap/codecache/perm gen等内存时,我惊讶地看到以下内容:

图片链接:

正如您在右侧的jconsole中看到的,当我分析相关内容时,堆正在增加,但当工作结束时,堆也会再次减小到其正常大小。在左边,您可以看到应用程序部署到的服务器的“htop”。这就是:RAM,尽管堆运行正常,垃圾收集器运行正常,难以置信的高达3,2gb

这让我很困惑。我在想,我的java虚拟机堆栈是否需要与此相关?我做了一些研究,发现虚拟机堆栈是一个只有几兆字节(甚至只有kb)的小内存

我的技术背景:

  • 该应用程序正在glassfish v.3.1.2上运行
  • 数据库正在MySQL上运行
  • Hibernate被用作ORM框架
  • Java版本是1.7.0_04
  • 它是用VAADIN实现的
  • MySQL数据库和glassfish是此服务器上唯一运行的东西
  • 在分析过程中,我正在使用JAXB构建XML DOM样式的文档,并将它们保存在数据库中
  • 上载的文档为.txt或.pdf文件
  • 操作系统是linux
解决方案?

你知道为什么会发生这种情况,以及我能做些什么来修复它吗?我现在真的很惊讶,因为我认为内存问题来自导致堆爆炸的内存泄漏。但现在,堆不是问题所在。当堆保持在同一级别时,RAM会越来越高。我不知道该怎么解决它

感谢您与我分享的每一个想法。

编辑:也许我还应该指出,这种行为目前使我无法真正让其他人使用我的应用程序。当RAM已满且服务器不再响应时,我退出

Edit2:也许我还应该补充一点,每次成功的进一步分析之后,这个RAM都会不断增加。

JVM实现中使用内存的东西比堆设置多得多。 通过
-Xmx
进行的堆设置仅控制Java堆,它不控制JVM对本机内存的消耗,而JVM的本机内存消耗根据实现完全不同

从下面的文章

维护堆和垃圾收集器会使用无法控制的本机内存

需要更多本机内存来维护的状态 维护Java堆的内存管理系统。数据结构 必须分配用于跟踪可用存储并在以下情况下记录进度 收集垃圾。这些数据结构的确切大小和性质 不同的实现会有所不同,但许多都与应用程序的大小成比例 堆

JIT编译器使用本机内存,就像
javac
一样

字节码编译使用本机内存(与静态 编译器(如gcc)需要内存才能运行),但 字节码)和来自JIT的输出(可执行代码) 存储在本机内存中。包含许多 JIT编译的方法比较小的应用程序使用更多的本机内存

然后是使用本机内存的类加载器

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

我甚至不会引用线程的部分,我想你会明白 Java堆不是JVM实现中唯一消耗内存的东西,不是所有东西 进入JVM堆,堆占用的本地内存比您指定的要多 管理和簿记

本机代码 很多时候,应用程序服务器都有在JVM之外运行的本机代码,但仍然作为与控制应用程序服务器的进程相关联的内存显示在操作系统上。

JVM实现中使用内存的东西比堆设置多得多。 通过
-Xmx
进行的堆设置仅控制Java堆,它不控制JVM对本机内存的消耗,而JVM的本机内存消耗根据实现完全不同

从下面的文章

维护堆和垃圾收集器会使用无法控制的本机内存

需要更多本机内存来维护的状态 维护Java堆的内存管理系统。数据结构 必须分配用于跟踪可用存储并在以下情况下记录进度 收集垃圾。这些数据结构的确切大小和性质 不同的实现会有所不同,但许多都与应用程序的大小成比例 堆

JIT编译器使用本机内存,就像
javac
一样

字节码编译使用本机内存(与静态 编译器(如gcc)需要内存才能运行),但 字节码)和来自JIT的输出(可执行代码) 存储在本机内存中。包含许多 JIT编译方法使用更多的