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

时间:2015-10-08 23:11:57

标签: java memory jenkins jvm jetty

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

首先,基础知识:

  • Jenkins 1.631
  • 通过war文件中嵌入的码头运行
  • OpenJDK 1.7.0_51
  • Oracle Linux(3.8.13-55.1.5.el6uek.x86_64)
  • 386 GB ram
  • 40核

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

我做了一些研究并且我知道问题是什么,但是如何解决它却不知所措。我怀疑我遇到了here提到的虚拟内存过度使用问题;来自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粗略地捕获了线程数,发现40核心机器上的线程数大约为114,而24核心机器上的线程数为84。

这个解释看起来好听吗?只要它......

  1. 有没有办法配置Jenkins以减少它在启动时产生的线程数?我尝试了所讨论的论据here,但正如所宣传的那样,它们似乎没有任何效果。
  2. 是否有可用的虚拟机没有过度使用问题,或者有其他配置选项可以解决它?
  3. 此时的最佳选择可能是在虚拟化环境中运行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 overcommit理论。

    编辑#2

    PerMichałGrzejszczak,这是与Red Hat Enterprise Linux 6一起分发的glibc问题here。在我的案例MALLOC_ARENA_MAX中,可以通过显式设置环境变量export MALLOC_ARENA_MAX=2来解决此问题。如果没有明确设置此变量,JVM显然会尝试生成(8 x cpu核心数)线程,每个线程消耗64M。我的40个核心案例需要10个演出的虚拟ram向北,超过(我自己)8台演出机器上的ulimit。将此值设置为2会将VM消耗降低到大约128兆。

1 个答案:

答案 0 :(得分:1)

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

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

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