gpt4 book ai didi

jvm-arguments - 限制 Java 8 内存消耗

转载 作者:行者123 更新时间:2023-12-04 06:28:23 25 4
gpt4 key购买 nike

我在 64 位 Ubuntu VM 上运行三个 Java 8 JVM,该 VM 是从最小安装构建的,除了三个 JVM 之外没有额外运行。 VM 本身有 2GB 内存,每个 JVM 都受到 -Xmx512M 的限制,我认为这很好,因为会有几百 MB 的空闲空间。

几周前,一个系统崩溃了,hs_err_pid 转储显示:

# There is insufficient memory for the Java Runtime Environment to continue.
# Native memory allocation (mmap) failed to map 196608 bytes for committing reserved memory.
# Possible reasons:
# The system is out of physical RAM or swap space
# In 32 bit mode, the process size limit was hit
# Possible solutions:
# Reduce memory load on the system
# Increase physical memory or swap space
# Check if swap backing store is full
# Use 64 bit Java on a 64 bit OS
# Decrease Java heap size (-Xmx/-Xms)
# Decrease number of Java threads
# Decrease Java thread stack sizes (-Xss)
# Set larger code cache with -XX:ReservedCodeCacheSize=
# This output file may be truncated or incomplete.

我重新启动了 JVM,将堆大小减小到 384MB,到目前为止一切正常。但是,当我当前使用 ps 命令查看 VM 并按 RSS 大小降序排序时,我看到了

RSS %MEM    VSZ   PID CMD
708768 35.4 2536124 29568 java -Xms64m -Xmx512m ...
542776 27.1 2340996 12934 java -Xms64m -Xmx384m ...
387336 19.3 2542336 6788 java -Xms64m -Xmx512m ...
12128 0.6 288120 1239 /usr/lib/snapd/snapd
4564 0.2 21476 27132 -bash
3524 0.1 5724 1235 /sbin/iscsid
3184 0.1 37928 1 /sbin/init
3032 0.1 27772 28829 ps ax -o rss,pmem,vsz,pid,cmd --sort -rss
3020 0.1 652988 1308 /usr/bin/lxcfs /var/lib/lxcfs/
2936 0.1 274596 1237 /usr/lib/accountsservice/accounts-daemon
..
..

自由命令显示

              total        used        free      shared  buff/cache   available
Mem: 1952 1657 80 20 213 41
Swap: 0 0 0

以第一个进程为例,尽管堆限制为 524288 KB (512*1024),但 RSS 大小为 708768 KB。

我知道在 JVM 堆上使用了额外的内存,但问题是我如何控制它以确保我不会再次耗尽内存?我正在尝试将每个 JVM 的堆大小设置得尽可能大而不会使它们崩溃。

或者是否有关于如何根据整体内存可用性设置 JVM 堆大小的通用指南?

最佳答案

似乎没有办法控制 JVM 在堆上使用多少额外内存。但是,通过在一段时间内监视应用程序,可以获得对此数量的良好估计。如果 java 进程的总体消耗高于预期,则可以减小堆大小。需要进一步监控以确定这是否会影响性能。

继续上面的示例并使用命令 ps ax -o rss,pmem,vsz,pid,cmd --sort -rss 我们今天看到的用法是

  RSS %MEM    VSZ   PID CMD
704144 35.2 2536124 29568 java -Xms64m -Xmx512m ...
429504 21.4 2340996 12934 java -Xms64m -Xmx384m ...
367732 18.3 2542336 6788 java -Xms64m -Xmx512m ...
13872 0.6 288120 1239 /usr/lib/snapd/snapd
..
..

这些 java 进程都在运行相同的应用程序,但具有不同的数据集。第一个进程 (29568) 使用超过堆限制的大约 190M 保持稳定,而第二个 (12934) 从 156M 减少到 35M。第三个的总内存使用量一直保持在堆大小以下,这表明可以减少堆限制。

似乎在这里为每个 Java 进程允许 200MB 额外的非堆内存已经绰绰有余,因为这总共提供了 600MB 的余地。从 2GB 中减去它剩下 1400MB,所以三个 -Xmx 参数值的总和应该小于这个数量。

从阅读 Fairoz 在评论中指出的文章中可以了解到,JVM 可以使用许多不同的方式使用非堆内存。其中一个可测量的是线程堆栈大小。可以在 linux 上使用 java -XX:+PrintFlagsFinal -version | 找到 JVM 的默认值。 grep ThreadStackSize 在上面的例子中它是 1MB,因为有大约 25 个线程,我们可以有把握地说至少总是需要 25MB 的额外空间。

关于jvm-arguments - 限制 Java 8 内存消耗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47793089/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com