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

时间:2012-06-13 21:01:04

标签: java glassfish stack heap

  

可能重复:
  Limit jvm process memory on ubuntu

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

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

当我在一些运行后用jconsole观察堆/ codecache / perm gen等内存时,我很惊讶,因为我看到了以下内容:

check

图片链接:https://www7.pic-upload.de/13.06.12/murk9qrka8al.png

正如您在右侧的jconsole中看到的那样,当我正在进行与分析相关的事情时,堆正在增加,但是当工作结束时,它也会再次减少到正常大小。在左侧,您可以看到部署应用程序的服务器的“htop”。它是:RAM是,虽然堆正常运行,但垃圾收集器似乎运行正常,难以置信高达近2,2gb。

现在这让我很困惑。我在想我的java vm堆栈是否可以对此做些什么?我做了一些研究,我发现了关于vm堆栈的内容,它只是一个只有几兆字节(甚至只有kb)的小内存。

我的技术背景:

  • 该应用程序在glassfish v.3.1.2上运行
  • 数据库正在MySQL上运行
  • Hibernate用作ORM框架
  • Java版本是1.7.0_04
  • 使用VAADIN实现
  • MySQL数据库和glassfish是此服务器上运行的唯一内容
  • 我在分析期间使用JAXB构建XML-DOM样式的文档并将它们保存在数据库中
  • 上传的文件是.txt或.pdf文件
  • OS是linux

解决方案吗

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

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

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

编辑2:也许我还应该补充一点,在每次成功进一步分析后,这个RAM会不断增加。

1 个答案:

答案 0 :(得分:1)

在JVM实现中使用内存的内容远远多于堆设置。

通过-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外部运行的本机代码,但仍然显示为与控制应用服务器的进程关联的内存。