Jenkins在执行器上使用100%CPU构建作业

Jenkins在执行器上使用100%CPU构建作业,jenkins,junit,mockito,maven-surefire-plugin,byte-buddy,Jenkins,Junit,Mockito,Maven Surefire Plugin,Byte Buddy,目前,我们看到Jenkins机器的CPU使用率为100%或200%或400%,这取决于top中的内核数量: PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 23376 ec2-user 20 0 4220m 100m 0 S 99.2 1.3 324945:21 java 这些JVM进程即使在构建完成后,并且当前没有运行任何构建时,也会一直存在。主

目前,我们看到Jenkins机器的CPU使用率为100%或200%或400%,这取决于top中的内核数量:

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                      
23376 ec2-user  20   0 4220m 100m    0 S 99.2  1.3 324945:21 java
这些JVM进程即使在构建完成后,并且当前没有运行任何构建时,也会一直存在。主节点和从节点上的构建都会出现此问题。运行从代理的JVM本身具有完全正常的CPU使用率

一旦我最终能够获得一个线程转储,就只有一个非系统线程可以运行并且不等待锁:

"main" #1 prio=5 os_prio=0 tid=0x00007f0834008800 nid=0x5b51 runnable [0x00007f083abf3000]
java.lang.Thread.State: RUNNABLE
at java.util.HashMap.put(HashMap.java:611)
at java.util.HashSet.add(HashSet.java:219)
at net.bytebuddy.dynamic.scaffold.MethodGraph$Compiler$Default$Key$Harmonized.detach(MethodGraph.java:878)
at net.bytebuddy.dynamic.scaffold.MethodGraph$Compiler$Default$Key$Store$Entry$Resolved.asNode(MethodGraph.java:1331)
at net.bytebuddy.dynamic.scaffold.MethodGraph$Compiler$Default$Key$Store.asGraph(MethodGraph.java:1138)
at net.bytebuddy.dynamic.scaffold.MethodGraph$Compiler$Default.compile(MethodGraph.java:507)
at net.bytebuddy.dynamic.scaffold.MethodGraph$Compiler$AbstractBase.compile(MethodGraph.java:423)
at net.bytebuddy.dynamic.scaffold.MethodRegistry$Default.prepare(MethodRegistry.java:489)
at net.bytebuddy.dynamic.scaffold.subclass.SubclassDynamqicTypeBuilder.make(SubclassDynamicTypeBuilder.java:153)
at net.bytebuddy.dynamic.DynamicType$Builder$AbstractBase$Delegator.make(DynamicType.java:2508)
at org.mockito.internal.creation.bytebuddy.MockBytecodeGenerator.generateMockClass(MockBytecodeGenerator.java:60)
at org.mockito.internal.creation.bytebuddy.CachingMockBytecodeGenerator$CachedBytecodeGenerator.generate(CachingMockBytecodeGenerator.java:72)
at org.mockito.internal.creation.bytebuddy.CachingMockBytecodeGenerator$CachedBytecodeGenerator.getOrGenerateMockClass(CachingMockBytecodeGenerator.java:64)
at org.mockito.internal.creation.bytebuddy.CachingMockBytecodeGenerator.get(CachingMockBytecodeGenerator.java:27)
at org.mockito.internal.creation.bytebuddy.ByteBuddyMockMaker.createProxyClass(ByteBuddyMockMaker.java:54)
at org.mockito.internal.creation.bytebuddy.ByteBuddyMockMaker.createMock(ByteBuddyMockMaker.java:27)
at org.mockito.internal.util.MockUtil.createMock(MockUtil.java:32)
at org.mockito.internal.MockitoCore.mock(MockitoCore.java:55)
at org.mockito.Mockito.mock(Mockito.java:1449)
at org.mockito.internal.configuration.MockAnnotationProcessor.process(MockAnnotationProcessor.java:33)
at org.mockito.internal.configuration.MockAnnotationProcessor.process(MockAnnotationProcessor.java:16)
at org.mockito.internal.configuration.DefaultAnnotationEngine.createMockFor(DefaultAnnotationEngine.java:43)
at org.mockito.internal.configuration.DefaultAnnotationEngine.process(DefaultAnnotationEngine.java:66)
at org.mockito.internal.configuration.InjectingAnnotationEngine.processIndependentAnnotations(InjectingAnnotationEngine.java:71)
at org.mockito.internal.configuration.InjectingAnnotationEngine.process(InjectingAnnotationEngine.java:55)
at org.mockito.MockitoAnnotations.initMocks(MockitoAnnotations.java:108)
at org.mockito.internal.runners.JUnit45AndHigherRunnerImpl$1.withBefores(JUnit45AndHigherRunnerImpl.java:27)
at org.junit.runners.BlockJUnit4ClassRunner.methodBlock(BlockJUnit4ClassRunner.java:276)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.mockito.internal.runners.JUnit45AndHigherRunnerImpl.run(JUnit45AndHigherRunnerImpl.java:37)
at org.mockito.runners.MockitoJUnitRunner.run(MockitoJUnitRunner.java:62)
at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:59)
at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.executeTestSet(AbstractDirectoryTestSuite.java:115)
at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.execute(AbstractDirectoryTestSuite.java:102)
at org.apache.maven.surefire.Surefire.run(Surefire.java:180)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.apache.maven.surefire.booter.SurefireBooter.runSuitesInProcess(SurefireBooter.java:350)
at org.apache.maven.surefire.booter.SurefireBooter.main(SurefireBooter.java:1021)
我进行了几个连续的线程转储,这个线程几乎总是在同一个位置——HashMap.putHashMap.java:611——而JVM占用了100%的CPU。发生这种情况时,我还没有机会附加调试器,但我只是想看看是否有人认识到这是一个已知的bug。对我来说,它看起来像一个热旋转的无休止的循环,试图一次又一次地向散列映射添加某些项。这可能与Jenkins有关,但其他出现在堆栈跟踪中的主要玩家显然是Maven Surefire、JUnit、Mockito和ByteBuddy,很抱歉包含了所有这些标签


我不能可靠地重现这个问题,不幸的是,我也不知道我们数百个构建中的哪一个留下了这些糟糕的JVM。为了完整性起见,环境是Jenkins 2.46.1、Maven 3.3.3、Surefire 2.19.1、JUnit 4.12,但不幸的是,它有一系列不同的Mockito版本,因此也有ByteBuddy版本。我希望有人能认识到这是一个相关组件中的已知错误,并能提出解决方案…

您能用最新版本的Mockito重试吗?这似乎是我们用于模拟创建的新锁定机制的一个问题。以前,我们只对所有类型使用一个锁,现在锁更细粒度


您看到的堆栈跟踪是在模拟创建中,Byte Buddy在其中构建由类定义的方法的结构。它需要这样做,以解决层次结构下的桥接方法。这是一个相当昂贵的操作,但它不应该无休止地旋转。你有50+级别的非常深的层次结构的类吗?

FWIW,仔细检查堆栈跟踪如何与Mockito的不同版本中的代码对齐,代码路径似乎建议Mockito 2.0.44-beta!因此是ByteBuddy 1.2.3。所以,在非测试版的Mockito中,这可能不再是一个问题……我同意:Mockito2.0早已过时。如果您因为使用PowerMockito而被限制为该特定版本。。。欢迎来到痛苦的世界。这就是为什么我们停止使用PowerMockito;请继续使用Mockito的最新版本。谢谢你对这里可能发生的事情做了一些解释。我们正在升级所有仍然使用Mockito 2.0.44-beta的项目。我会提供一个更新,如果它修复。WRT类层次结构深度:如果不对我们所有的代码库进行详细分析,我无法100%确定,但我高度怀疑我们的任何项目的层次结构深度是否超过50层。