Java内存使用量比堆+非堆

时间:2019-02-15 16:56:50

标签: java spring-boot docker memory heap-memory

我有一个SpringBoot版本为2.1.1.RELEASE的Java应用程序(Oracle JDK 8u191),并且我遇到了奇怪的内存使用情况(不要认为这与spring有关)。

应用程序提供的HEAP和NONHEAP值的总和比Docker报告的实际内存使用量低得多。

我知道Java除了HEAP和NONHEAP之外还有其他内存区域,但是我不知道如何测量它们以及当前行为是否正常。

目前,我的应用程序报告了以下内容(在生产环境中运行3天后):

           Init       Used       Committed       Max       
HEAP:      250M       79M        250M            800M      
NONHEAP:   2M         192M       201M            0M     

springBoot的执行器端点/metrics报告相同的内存使用情况。

但是docker stats命令报告了此情况(在容器smem内部为Java进程报告了相同的值)

MEM USAGE / LIMIT
750.2MiB / 1.172GiB

堆+非堆与当前使用的内存之间的差为299,2mb

我没想到我们第一次将这项服务投入生产时会有300mb的空间,直到我们找到了正确的配置,这才导致大量的OOM。

即使在GC之后,这种“未注册的内存使用情况”似乎只会增加而不会减少。

如果我重新开始复制​​,则实际使用的堆+非堆之间的差异约为100mb。

我的Dockerfile以此方式启动应用程序:

ENTRYPOINT ["java", "-Xms250m", "-Xmx800m", "-XX:+UseG1GC", "-Djava.security.egd=file:/dev/./urandom", "-jar", "/app.jar"]

我还有一个计划的例行程序,该程序每小时运行System.gc()来缩减已提交的内存,因为该服务在一天中有很小的高峰,并且我希望未使用的内存可用于其他服务。

我想知道这种行为是否正常。而我该如何衡量正在使用那么多内存的内容呢? visualvm和jconsole仅显示堆和非堆。似乎springBoot执行器中也没有指标可以测量。

我应该在容器中为这种使用留出多少内存?我找不到关于它的任何有用的文章。

编辑1:

7天后,(堆+非堆)总和之间的差值变为550mb,这使我的容器没有了任何存储空间。

编辑2:

深入研究本文后,事情才有意义:

Java process memory usage deviation from jcmd committed memory

Where do these java native memory allocated from?

Java process memory usage (jcmd vs pmap)

实际上,我们正在使用带有内存泄漏报告的第三方库:compile("axis:axis-wsdl4j:1.5.1")

我将尝试升级到Axis2,并将结果发布在这里。

0 个答案:

没有答案