JMeter - linux 内存不足

JMeter - out of memory on linux

我正在尝试 运行 对应用程序进行负载测试。为此,我在 Ubuntu Vm 上使用 JMeter (v.2.13),配备 60GB Ram 和足够的 CPU 功率。目标是达到 10k 用户通过 WebSocket 连接。

但是在测试期间 运行s 我在 ssh 控制台上收到以下错误(大约 1.5k 到 2.5k 模拟用户)

OpenJDK 64-Bit Server VM warning: Attempt to protect stack guard pages failed.
OpenJDK 64-Bit Server VM warning: Attempt to deallocate stack guard pages failed.
OpenJDK 64-Bit Server VM warning: INFO: os::commit_memory(0x00007f20ee653000, 12288, 0) failed; error='Cannot allocate memory' (errno=12)
#
# There is insufficient memory for the Java Runtime Environment to continue.
# Native memory allocation (malloc) failed to allocate 12288 bytes for committing reserved memory.
# An error report file with more information is saved as:
# /jmetertests/jm/bin/hs_err_pid1833.log
OpenJDK 64-Bit Server VM warning: Attempt to deallocate stack guard pages failed.
OpenJDK 64-Bit Server VM warning: INFO: os::commit_memory(0x00007f2218de8000, 12288, 0) failed; error='Cannot allocate memory' (errno=12)

提到的错误报告文件如下所示

# There is insufficient memory for the Java Runtime Environment to continue.
# Native memory allocation (malloc) failed to allocate 12288 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.
#
#  Out of Memory Error (os_linux.cpp:2798), pid=1833, tid=140472285792000
#
# JRE version: OpenJDK Runtime Environment (7.0_75-b13) (build 1.7.0_75-b13)
# Java VM: OpenJDK 64-Bit Server VM (24.75-b04 mixed mode linux-amd64 )
# Derivative: IcedTea 2.5.4
# Distribution: Ubuntu 14.04 LTS, package 7u75-2.5.4-1~trusty1
# Failed to write core dump. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again

我试图通过在 .sh 文件中发出 java-命令之前添加以下行来修改 jmeter.sh 来分配更多内存:

JVM_ARGS="-Xms5g -Xmx20g -Xss300k"

我还尝试使用以下命令设置 _JAVA_OPTIONS 环境变量

export _JAVA_OPTIONS="-Xms5g -Xmx20g"

最后我在一些 SO-thread 中找到了这个命令

sysctl -w vm.max_map_count=500000

top-命令为我提供了以下有关内存的信息

KiB Mem:  61836576 total, 15163400 used, 46673176 free,    10636 buffers
KiB Swap:        0 total,        0 used,        0 free.    94492 cached Mem

更新

仅供参考:除了简单的数据编写器外,我没有在 JMeter 中使用任何侦听器。但是,即使我禁用了最后一个侦听器,也会抛出错误。

java -Xms40g -version

成功了——原来我真的可以分配这么多内存了

我使用

减少了堆栈大小
-Xss300k

这至少改变了一些东西,因为我现在得到了

Uncaught Exception java.lang.OutOfMemoryError:
unable to create new native thread. See log file for details.

错误。系统线程数好像用完了?

更新2

根据一些用户的要求结果uf ulimit -a

core file size          (blocks, -c) 0
scheduling priority             (-e) 0
pending signals                 (-i) 491456
max locked memory       (kbytes, -l) 64
open files                      (-n) 500000
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
max user processes              (-u) 491456
... all other entries are set to 'unlimited'

并且 limits.conf 包含以下条目

*         hard    nofile      900000
*         soft    nofile      900000
root      hard    nofile      900000
root      soft    nofile      900000

此外,我已将 proc/sys/kernel 下的 threads-max 设置为荒谬的高值,并且还增加了 proc/sys/vm/max_map_count

的值

我是漏掉了什么还是做错了什么? 谢谢你的帮助。

首先检查是否可以通过以下命令分配多达50G的堆:

java -Xms50G -version

如果不成功 - 尝试减小最小堆大小,除非您看到 Java 版本信息没有错误。

只要您没有收到java.lang.OutOfMemoryError: Java heap space错误,我相信您的堆大小调整已成功应用。

也许您启用了内存密集型侦听器,例如 View Results Tree or View Results in Table?如果是这样 - 禁用它们(以及任何其他听众)

如果可能,请尝试切换到 Oracle JDK,至少 Java 6 存在巨大的性能差异。

还要确保您遵循 JMeter Performance and Tuning Tips 指南中的建议。

好的,同时我想通了:

  1. 确保阅读 Dmriti T 的 post
  2. 将 java 的堆栈大小设置为较小的值 - 通常最小值就足够了。在我的例子中是 200k(另见第 4 点。)
  3. 增加打开文件的最大数量 sysctl.conf(参见第 4 点)
  4. 增加堆大小 - 但由于 jmeter 将创建大量线程,因此也会为线程在 OS 级别上需要的内存留出足够的 space(因此新线程需要 OS 和 java 堆 - 因此也留下 os 足够的内存)(见下文)
  5. 更新 limits.conf(见下文)
  6. 更新 sysctl.conf-文件(见下文)

limits.conf

/etc/security/limits.conf

*         hard    nofile      900000
*         soft    nofile      900000
root      hard    nofile      900000
root      soft    nofile      900000

sysctl.conf

/etc/sysctl.conf

kernel.pid_max=999999
kernel.thread-max=999999
vm.max_map_count=999999
fs.file-max=999999

注意:是pid_max和thread-max

jmeter.sh / jmeter.bat

您会在 jmeter 安装的 /bin/ 文件夹中找到 ose。

在 linux 下添加行

JVM_ARGS="-Xmx15g -Xss250k"

最后一行实际 java 调用之前的某处。这将减少为每个线程分配的堆栈大小。

在 windows 下,您必须编辑 jmeter.bat。 我没有在 windows 下配置它,但至少关于堆应该有一行以 set HEAP 开头。我不知道 windows.

下的 -Xss 参数放在哪里