尽管堆保持不变,Java RAM 会增加? [复制]

Posted

技术标签:

【中文标题】尽管堆保持不变,Java RAM 会增加? [复制]【英文标题】:Java RAM increases although Heap stays same? [duplicate] 【发布时间】:2012-06-13 21:01:03 【问题描述】:

可能重复:Limit jvm process memory on ubuntu

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

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

当我在一些运行后使用 jconsole 观察堆/codecache/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 会不断增加。

【问题讨论】:

你能看到图片吗?否则,这是链接:www7.pic-upload.de/13.06.12/murk9qrka8al.png 了解操作系统会有所帮助。 Linux?思考:htop是虚拟内存占用,与已分配堆有很大不同。复制垃圾收集器通常依赖于空闲空间等于分配的堆空间,所以这里也许没有错。 我认为您以某种方式保留(或代码是)比所需更多的 RAM,但这可能是一种安全措施。就像使用固定大小的 Array 一样,RAM 使用量会更少。但是如果你使用像 ArrayList 这样没有固定大小的东西,那么它会占用更多的 RAM 等。这是一个简单的例子,但可能就是原因。 操作系统是Linux,感谢评论 我的问题是内存使用率越来越高,而不是一般来说更大的尺寸不会以更大的方式减少和增加 【参考方案1】:

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

通过-Xmx 设置的Heap 只控制Java Heap,它不控制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)并且可能使用第三方 图书馆。这些类需要在内存中存储多久 他们正在被使用。类的存储方式因实现而异。

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

本机代码

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

【讨论】:

以上是关于尽管堆保持不变,Java RAM 会增加? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

Java 如何在 RAM 中存储原始类型? [复制]

数据结构:堆 的详解

实时索引 DSE

visio复制粘贴时怎样保持原图形形状不变

C++ 隐藏符号会增加重定位时间

减少 Java 堆大小