繁体   English   中英

Jenkins 服务器启动时“内存不足”

[英]"Insufficient memory" on Jenkins server startup

Jenkins 的第一次用户,开始使用时遇到了一些麻烦。 我从 Linux shell 运行如下命令:

java -Xms512m -Xmx512m -jar jenkins.war

并始终收到如下错误:

# There is insufficient memory for the Java Runtime Environment to continue.
# pthread_getattr_np
# An error report file with more information is saved as:
# /home/twilliams/.jenkins/hs_err_pid36290.log

一、基础知识:

  • 詹金斯 1.631
  • 通过嵌入在战争文件中的码头运行
  • OpenJDK 1.7.0_51
  • Oracle Linux (3.8.13-55.1.5.el6uek.x86_64)
  • 386 GB 内存
  • 40核

我在许多其他配置中也遇到了同样的问题:使用 Java Hotspot 1.8.0_60,通过 Apache Tomcat 运行,以及对-Xms/-Xmx/-Xss和类似选项使用各种不同的值。

我做了一些研究,并认为我知道问题是什么,但我不知道如何解决它。 我怀疑我遇到了这里提到的虚拟内存过量使用问题; 来自 ulimit 的相关位:

--($:)-- ulimit -a
...
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) 8388608
stack size              (kbytes, -s) 8192
virtual memory          (kbytes, -v) 8388608
...

如果我以 root 身份将虚拟内存限制加倍,我可以启动 Jenkins,但我不想以 root 用户身份运行 Jenkins。

另一种解决方法:一台即将退役的 48 GB 内存和 24 个内核的机器可以毫无问题地启动 Jenkins,虽然(我怀疑)只是勉强:根据 htop,它的虚拟内存占用量刚刚超过 8 GB。 因此,我怀疑内存过量使用问题是随着机器上处理器数量的增加而扩展的,大概是 Jenkins 启动与主机上存在的处理器数量成正比的线程数量的结果。 我通过ps -eLf | grep jenkins | wc -l粗略地捕获了线程数ps -eLf | grep jenkins | wc -l ps -eLf | grep jenkins | wc -l并发现线程数在 40 核机器上达到 114 左右,在 24 核机器上达到 84。

这个解释听起来合理吗? 前提是它...

  1. 有没有办法配置 Jenkins 以减少它在启动时产生的线程数? 我尝试了这里讨论的论点但正如宣传的那样,它们似乎没有任何效果。
  2. 是否有任何可用的虚拟机不会受到过度使用问题的影响,或者其他一些配置选项可以解决这个问题?

此时最明智的选择可能是在虚拟化环境中运行 Jenkins,以将其可支配的资源限制在合理范围内,但此时我对这个问题在智力层面感兴趣,并想知道如何得到这个顽固的配置行为。

编辑

这是 hs_error.log 文件中的一个片段,它指导了我的初步调查:

# There is insufficient memory for the Java Runtime Environment to continue.
# pthread_getattr_np
# 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.

这是我尝试过的几个命令行,所有结果都相同。

  • 从可怜的堆空间开始:
    • java -Xms2m -Xmx2m -Xss228k -jar jenkins.war
  • 从明显更多的堆空间开始:
    • java -Xms2048m -Xmx2048m -Xss1m -XX:ReservedCodeCacheSize=512m -jar jenkins.war
  • 成长空间:
    • java -Xms2m -Xmx1024m -Xss228k -jar jenkins.war

还尝试了许多其他配置。 最终,我不认为这里的问题是堆耗尽 - 这是 JVM 试图为自己保留过多的虚拟内存(用于存储堆、线程堆栈等),而不是 ulimit 设置允许的数量。 据推测,这是之前链接的过度使用问题的结果,因此如果 Jenkins 产生 120 个线程,它会错误地尝试保留主进程最初占用的 120 倍的 VM 空间。

使用该日志中建议的其他选项完成了我能做的一切之后,我试图弄清楚如何减少 Jenkins 中的线程数以测试线程 VM 过量使用理论。

编辑 #2

每米哈尔Grzejszczak,这是与红帽企业Linux 6分布讨论glibc的一个问题在这里 这个问题可以通过显式设置环境变量MALLOC_ARENA_MAX ,在我的例子中是export MALLOC_ARENA_MAX=2 如果没有显式设置这个变量,JVM 显然会尝试产生(8 x cpu 核心数)线程,每个线程消耗 64M。 我的 40 个核心案例需要向北 10 个演出虚拟内存,超过(本身)我机器上 8 个演出的 ulimit。 将此设置为 2 会将 VM 消耗减少到大约 128 兆。

Jenkins 内存占用更多​​地与其管理的项目数量和大小相关,而不是 CPU 或可用内存的数量。 Jenkins 应该可以在 1GB 的堆内存上正常运行,除非你有巨大的项目。

不过,您可能错误地配置了 JVM。 -Xmx 和 -Xms 参数控制 JVM 可以使用的堆空间。 -Xmx 是堆内存的限制,-Xms 是堆内存的起始值。 堆是整个 JVM 的单个内存区域。 您可以通过 JConsole 或 VisualVM 等各种工具轻松监控它。

另一方面 -Xss 与堆无关。 它是此 JVM 进程中所有线程的线程堆栈大小。 由于 Java 程序往往会创建大量线程,将此参数设置得太大可能会阻止您的程序启动。 通常,该值在 512 kb的范围内。 在这里输入 512 m反而会使 JVM 无法启动。 确保您的设置不包含任何此类错误(并发布您的内存配置)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM