Java 进程驻留内存
Posted
技术标签:
【中文标题】Java 进程驻留内存【英文标题】:Java Process Resident Memory 【发布时间】:2015-02-17 09:08:03 【问题描述】:我是 java 内存问题的新手,在调试 java 进程的内存使用时遇到问题,需要您的帮助。 按照“top”,java进程占用了8G的常驻内存和9.4G的虚拟内存。这对于该过程的作用来说太多了,我想检查它为什么会消耗内存。所以我使用 jmap 进行了堆转储(没有“live”选项,因为它可能会触发 GC),发现只有 100MB 的活动对象存在,并且有 1.5G 的无法访问的对象。那么剩下的 6G 内存去哪儿了?我应该检查哪些其他类型的非堆内存?另外,你能用任何工具/unix命令帮我找出来吗?
JVM 参数:-Xms 为 2G,-Xmx 为 8G
如果我应该在此处添加更多信息以便为您提供更多背景信息,请告诉我。
提前致谢。
【问题讨论】:
听起来像是内存泄漏,我不知道在 Java 中什么会导致这种行为,但也许我会找到一些东西。您能否发布一些代码或详细说明该程序的目的和作用? 它从服务接收数据,将其从自定义格式转换为 json 并写入另一个 Web 服务。它是实时发生的,除了转换所需的短暂持续时间外,不会将数据保留在内存中。它不断打开和关闭与源服务和目标服务的连接。 见***.com/questions/26041117/… 【参考方案1】:在 Linux 上,这可能会提供一些有用的信息:
pmap -x PID
有关pmap
的更多信息,请参阅man pmap
您还应该知道,在 glibc >= 2.10(Ubuntu >= 10.04,RHEL >= 6)的 Linux 上存在一个已知问题,会导致“内存丢失”。
治疗方法是设置
export MALLOC_ARENA_MAX=4
在 Google 或 *** 上搜索 MALLOC_ARENA_MAX 以了解更多信息。
您可能还想调整其他 malloc 选项以优化分配内存的低碎片:
# tune glibc memory allocation, optimize for low fragmentation
# limit the number of arenas
export MALLOC_ARENA_MAX=2
# disable dynamic mmap threshold, see M_MMAP_THRESHOLD in "man mallopt"
export MALLOC_MMAP_THRESHOLD_=131072
export MALLOC_TRIM_THRESHOLD_=131072
export MALLOC_TOP_PAD_=131072
export MALLOC_MMAP_MAX_=65536
【讨论】:
查看这个答案:***.com/a/35610063,它有更多关于 Java 原生内存泄漏的详细信息。【参考方案2】:你告诉 Java 它可能需要 8Gb,它确实做到了。也许您在短时间内将 JVM 内部的内存使用量增加到 8Gb;然后它会收集垃圾并丢弃价值 6.4Gb 的无法访问的对象。但是 JVM 不会将该内存返回给系统。
但是,当您的机器上的物理内存用完时,这些 6.4Gb 的未使用页面将被换出。您的机器中的内存还没有用完,所以它们仍然是 RSS 的一部分。至少,这是我有根据的猜测。
另请参阅:Is there a way to lower Java heap when not in use?
【讨论】:
感谢您的回复。你的意思是说,即使GC扔掉了6.4G的数据,我分配的这么多,常驻内存还是会显示8G?有没有办法找出当时使用的确切内存,live + unreachable,不包括未使用的内存? 好吧,如果我的想法是正确的,那么一旦有另一个需要物理内存的进程,它就应该从你的驻留集中删除。但是,如果您没有其他需要内存的进程,它将保留在那里。 好的。关于如何确定是否真的是这种情况(未使用的页面)或是否正在使用非堆内存的任何建议? 没有我知道的漂亮工具。但是您可以再次启动占用 8Gb 的 java 进程(或者编写其他只分配内存的东西,无论是在 Java 中还是在执行大 malloc 然后休眠的小型 C 程序中),看看这是否会减少您的 RSS第一个过程。 这是不正确的,即使 xmx 是 8g,java 也会返回内存它不会返回 2g 的 xms ......而且它很容易测试只需运行一个简单的程序并给它 8g xmx 然后看在视觉虚拟机上花一分钟以上是关于Java 进程驻留内存的主要内容,如果未能解决你的问题,请参考以下文章