相关疑难解决方法(0)

Java使用比堆大小更多的内存(或正确的Docker内存限制大小)

对于我的应用程序,Java进程使用的内存远远超过堆大小.

容器正在运行的系统开始出现内存问题,因为容器占用的内存比堆大小多得多.

堆大小设置为128 MB(-Xmx128m -Xms128m),而容器最多占用1 GB内存.在正常情况下,它需要500MB.如果docker容器具有以下限制(例如mem_limit=mem_limit=400MB),则该进程被OS的内存不足杀死所杀死.

你能解释为什么Java进程使用比堆更多的内存吗?如何正确调整Docker内存限制?有没有办法减少Java进程的堆外内存占用?


我使用JVM中的本机内存跟踪命令收集有关该问题的一些详细信息.

从主机系统,我获得容器使用的内存.

$ docker stats --no-stream 9afcb62a26c8
CONTAINER ID        NAME                                                                                        CPU %               MEM USAGE / LIMIT   MEM %               NET I/O             BLOCK I/O           PIDS
9afcb62a26c8        xx-xxxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.0acbb46bb6fe3ae1b1c99aff3a6073bb7b7ecf85   0.93%               461MiB / 9.744GiB   4.62%               286MB / 7.92MB      157MB / 2.66GB      57
Run Code Online (Sandbox Code Playgroud)

从容器内部,我获得进程使用的内存.

$ ps -p 71 -o pcpu,rss,size,vsize
%CPU   RSS  SIZE    VSZ
11.2 486040 580860 3814600
Run Code Online (Sandbox Code Playgroud)
$ jcmd 71 VM.native_memory
71:

Native Memory Tracking:

Total: reserved=1631932KB, committed=367400KB
-                 Java Heap (reserved=131072KB, …
Run Code Online (Sandbox Code Playgroud)

java linux memory jvm docker

95
推荐指数
3
解决办法
1万
查看次数

使用Java获取内存统计信息:Runtime vs. MemoryMXBean

我正在创建一个计划执行程序来读取JVM的内存使用情况.我有两种方法可以在正在运行的JVM中获取内存统计信息 - Runtime和MemoryMXBean,它们的方法之间有以下对应关系:

memoryMxBean.getHeapMemoryUsage().getUsed()      <=> runtime.totalMemory() - runtime.freeMemory()
memoryMxBean.getHeapMemoryUsage().getCommitted() <=> runtime.totalMemory()
memoryMxBean.getHeapMemoryUsage().getMax()       <=> runtime.maxMemory()
Run Code Online (Sandbox Code Playgroud)

除了MemoryMXBean提供的额外非堆内存使用信息之外,有什么理由可以让我更喜欢它而不是运行时,反之亦然?

java memory-profiling

9
推荐指数
1
解决办法
2054
查看次数

如何理解java.lang.management.MemoryMXBean和-Xms?

MemoryMXBean.getHeapMemoryUsage()

我有一个使用 -Xms512m -Xmx512m 运行的 jvm 进程,下面显示了该进程的 MemoryMXBean.getHeapMemoryUsage() :

    init     = 512M
    used     = 105M
    comitted = 491M
    max      = 491M
Run Code Online (Sandbox Code Playgroud)
  1. 为什么最大是491M(我预计是512M)?

此过程的MemoryMXBean.getNonHeapMemoryUsage() MemoryMXBean.getNonHeapMemoryUsage():

    init     = 2M
    used     = 25M
    comitted = 25M
    max      = 0M
Run Code Online (Sandbox Code Playgroud)
  1. 非堆(谁使用它)是什么意思?什么样的内存会被计入这个非堆呢?我只知道我们在java代码中使用的直接内存不会(我说得对吗?)

-Xms

  1. -Xms(初始堆大小)是什么意思?我曾经认为初始堆大小是jvm启动时jvm实际从os分配多少内存,但事实证明是错误的。顶部显示该 jvm 的 RES 接近 150m,但该 jvm 是使用 -Xms512M 运行的。

  2. 下面的公式正确吗(或者几乎正确-_-)?如果不是,还应该考虑什么?

total memory a jvm used = used of MemoryMXBean.getHeapMemoryUsage() 
+ used of MemoryMXBean.getNonHeapMemoryUsage()
+ the direct memory we used in application level
Run Code Online (Sandbox Code Playgroud)

任何事情都会受到赞赏!

java jvm

4
推荐指数
1
解决办法
2012
查看次数

标签 统计

java ×3

jvm ×2

docker ×1

linux ×1

memory ×1

memory-profiling ×1