1

可能重复:
限制 ubuntu 上的 jvm 进程内存

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

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

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

查看

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

正如您在右侧的 jconsole 中看到的那样,当我在做与分析相关的事情时,堆正在增加,但当工作结束时,它也会再次减小到正常大小。在左侧,您可以看到部署应用程序的服务器的“htop”。就是这样:虽然堆正常运行,而且垃圾收集器似乎也运行正常,但 RAM 是令人难以置信的高,几乎达到 3,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 文件
  • 操作系统是linux

解决方案?

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

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

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

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

4

1 回答 1

1

在 JVM 实现中使用内存的东西比堆设置要多得多。

Heap 设置-Xmx仅控制 Java Heap,它不控制JVM 对本机内存的消耗,根据实现,其消耗完全不同。

来自以下文章感谢内存(了解 JVM 如何在 Windows 和 Linux 上使用本机内存)

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

需要更多的本机内存来维护维护 Java 堆的内存管理系统的状态。收集垃圾时,必须分配数据结构来跟踪空闲存储和记录进度。这些数据结构的确切大小和性质因实现而异,但许多与堆的大小成正比。

javac并且 JIT 编译器像使用本机内存一样

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

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

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

我什至不会开始引用有关线程的部分,我认为您会认为 Java 堆并不是 JVM 实现中唯一消耗内存的东西,并非所有东西都在 JVM 堆中,并且堆占用了方式比您指定用于管理和簿记的更多本机内存。

本机代码

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

于 2012-06-13T21:56:37.210 回答