简体   繁体   English

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

[英]"Insufficient memory" on Jenkins server startup

First time user of Jenkins here, and having a bit of trouble getting it started. Jenkins 的第一次用户,开始使用时遇到了一些麻烦。 From the Linux shell I run a command like:我从 Linux shell 运行如下命令:

java -Xms512m -Xmx512m -jar jenkins.war

and consistently get an error like:并始终收到如下错误:

# 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

First, the basics:一、基础知识:

  • Jenkins 1.631詹金斯 1.631
  • Running via the jetty embedded in the war file通过嵌入在战争文件中的码头运行
  • OpenJDK 1.7.0_51 OpenJDK 1.7.0_51
  • Oracle Linux (3.8.13-55.1.5.el6uek.x86_64) Oracle Linux (3.8.13-55.1.5.el6uek.x86_64)
  • 386 GB ram 386 GB 内存
  • 40 cores 40核

I get the same problem with a number of other configurations as well: using Java Hotspot 1.8.0_60, running through Apache Tomcat, and using all sorts of different values for -Xms/-Xmx/-Xss and similar options.我在许多其他配置中也遇到了同样的问题:使用 Java Hotspot 1.8.0_60,通过 Apache Tomcat 运行,以及对-Xms/-Xmx/-Xss和类似选项使用各种不同的值。

I've done a fair bit of research and think I know what the problem is, but am at a loss as how to solve it.我做了一些研究,并认为我知道问题是什么,但我不知道如何解决它。 I suspect that I'm running into the virtual memory overcommit issue mentioned here ;我怀疑我遇到了这里提到的虚拟内存过量使用问题; the relevant bits from ulimit:来自 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
...

If I double the virtual memory limit as root, I can start Jenkins, but I'd rather not run Jenkins as the root user.如果我以 root 身份将虚拟内存限制加倍,我可以启动 Jenkins,但我不想以 root 用户身份运行 Jenkins。

Another workaround: a soon-to-be-decommissioned machine with 48 GB ram and 24 cores can start Jenkins without issue, though (I suspect) just barely: according to htop, its virtual memory footprint is just over 8 GB.另一种解决方法:一台即将退役的 48 GB 内存和 24 个内核的机器可以毫无问题地启动 Jenkins,虽然(我怀疑)只是勉强:根据 htop,它的虚拟内存占用量刚刚超过 8 GB。 I suspect, as a result, that the memory overcommit issue is scaling with the number of processors on the machine, presumably the result of Jenkins starting a number of threads proportional to the number of processors present on the host machine.因此,我怀疑内存过量使用问题是随着机器上处理器数量的增加而扩展的,大概是 Jenkins 启动与主机上存在的处理器数量成正比的线程数量的结果。 I roughly captured the thread count via ps -eLf | grep jenkins | wc -l我通过ps -eLf | grep jenkins | wc -l粗略地捕获了线程数ps -eLf | grep jenkins | wc -l ps -eLf | grep jenkins | wc -l and found that the thread count spikes at around 114 on the 40 core machine, and 84 on the 24 core machine. ps -eLf | grep jenkins | wc -l并发现线程数在 40 核机器上达到 114 左右,在 24 核机器上达到 84。

Does this explanation seem sound?这个解释听起来合理吗? Provided it does...前提是它...

  1. Is there any way to configure Jenkins to reduce the number of threads it spawns at startup?有没有办法配置 Jenkins 以减少它在启动时产生的线程数? I tried the arguments discussed here but, as advertised, they didn't seem to have any effect.我尝试了这里讨论的论点但正如宣传的那样,它们似乎没有任何效果。
  2. Are there any VMs available that don't suffer from the overcommit issue, or some other configuration option to address it?是否有任何可用的虚拟机不会受到过度使用问题的影响,或者其他一些配置选项可以解决这个问题?

The sanest option at this point may be to just run Jenkins in a virtualized environment to limit the resources at its disposal to something reasonable, but at this point I'm interested in this problem on an intellectual level and want to know how to get this recalcitrant configuration to behave.此时最明智的选择可能是在虚拟化环境中运行 Jenkins,以将其可支配的资源限制在合理范围内,但此时我对这个问题在智力层面感兴趣,并想知道如何得到这个顽固的配置行为。

Edit编辑

Here's a snippet from the hs_error.log file, which guided my initial investigation:这是 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.

Here are a couple of command lines I tried, all with the same result.这是我尝试过的几个命令行,所有结果都相同。

  • Starting with a pitiful amount of heap space:从可怜的堆空间开始:
    • java -Xms2m -Xmx2m -Xss228k -jar jenkins.war
  • Starting with significantly more heap space:从明显更多的堆空间开始:
    • java -Xms2048m -Xmx2048m -Xss1m -XX:ReservedCodeCacheSize=512m -jar jenkins.war
  • Room to grow:成长空间:
    • java -Xms2m -Xmx1024m -Xss228k -jar jenkins.war

A number of other configurations were tried as well.还尝试了许多其他配置。 Ultimately I don't think that the problem is heap exhaustion here - it's that the JVM is trying to reserve too much virtual memory for itself (in which to store the heap, thread stacks, etc) than allowed by the ulimit settings.最终,我不认为这里的问题是堆耗尽 - 这是 JVM 试图为自己保留过多的虚拟内存(用于存储堆、线程堆栈等),而不是 ulimit 设置允许的数量。 Presumably this is the result of the overcommit issue linked earlier, such that if Jenkins is spawning 120 threads, it's erroneously trying to reserve 120x as much VM space as the master process originally occupied.据推测,这是之前链接的过度使用问题的结果,因此如果 Jenkins 产生 120 个线程,它会错误地尝试保留主进程最初占用的 120 倍的 VM 空间。

Having done what I could with the other options suggested in that log, I'm trying to figure out how to reduce the thread count in Jenkins to test the thread VM overcommit theory.使用该日志中建议的其他选项完成了我能做的一切之后,我试图弄清楚如何减少 Jenkins 中的线程数以测试线程 VM 过量使用理论。

Edit #2编辑 #2

Per Michał Grzejszczak, this is an issue with the glibc distributed with Red Hat Enterprise Linux 6 as discussed here .每米哈尔Grzejszczak,这是与红帽企业Linux 6分布讨论glibc的一个问题在这里 The issue can be worked around via explicit setting of the environment variable MALLOC_ARENA_MAX , in my case export MALLOC_ARENA_MAX=2 .这个问题可以通过显式设置环境变量MALLOC_ARENA_MAX ,在我的例子中是export MALLOC_ARENA_MAX=2 Without explicit setting of this variable, the JVM will apparently attempt to spawn (8 x cpu core count) threads, each consuming 64M.如果没有显式设置这个变量,JVM 显然会尝试产生(8 x cpu 核心数)线程,每个线程消耗 64M。 My 40 core case would have required northward of 10 gigs of virtual ram, exceeding (by itself) the ulimit on my machine of 8 gigs.我的 40 个核心案例需要向北 10 个演出虚拟内存,超过(本身)我机器上 8 个演出的 ulimit。 Setting this to 2 reduces VM consumption to around 128 megs.将此设置为 2 会将 VM 消耗减少到大约 128 兆。

Jenkins memory footprint is related more to the number and size of projects it is managing than the number of CPUs or available memory. Jenkins 内存占用更多​​地与其管理的项目数量和大小相关,而不是 CPU 或可用内存的数量。 Jenkins should run fine on 1GB of heap memory unless you have gigantic projects on it. Jenkins 应该可以在 1GB 的堆内存上正常运行,除非你有巨大的项目。

You may have misconfigured the JVM though.不过,您可能错误地配置了 JVM。 -Xmx and -Xms parameters govern heap space JVM can use. -Xmx 和 -Xms 参数控制 JVM 可以使用的堆空间。 -Xmx is a limit for heap memory, -Xms is a starting value for heap memory. -Xmx 是堆内存的限制,-Xms 是堆内存的起始值。 Heap is a single memory area for entire JVM.堆是整个 JVM 的单个内存区域。 You can easily monitor it by various tools like JConsole or VisualVM.您可以通过 JConsole 或 VisualVM 等各种工具轻松监控它。

On the other hand -Xss is not related to heap.另一方面 -Xss 与堆无关。 It is the size of a thread stack for all threads in this JVM process.它是此 JVM 进程中所有线程的线程堆栈大小。 As Java programs tend to create numerous threads setting this parameter too big can prevent your program from launching.由于 Java 程序往往会创建大量线程,将此参数设置得太大可能会阻止您的程序启动。 Typically this value is in the range of 512 kb .通常,该值在 512 kb的范围内。 Entering here 512 m instead makes it impossible for JVM to start.在这里输入 512 m反而会使 JVM 无法启动。 Make sure your settings do not contain any such mistakes (and post your memory config too).确保您的设置不包含任何此类错误(并发布您的内存配置)。

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

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