【问题标题】:The JVM should have exited but did notJVM 应该已经退出但没有
【发布时间】:2019-03-29 22:34:43
【问题描述】:

在非 gui 模式下使用 Jmeter 3.3 进行分布式测试期间出现错误,我该如何解决:

我在 Master 和 Slave 机器上使用相同版本的 JMeter 和 JDK。

JVM 应该已经退出但没有。 以下非守护线程仍在运行(DestroyJavaVM 可以): 线程[main,5,main],

stackTrace:java.net.SocketInputStream#socketRead0
java.net.SocketInputStream#socketRead
java.net.SocketInputStream#read
java.net.SocketInputStream#read
java.io.BufferedInputStream#fill
java.io.BufferedInputStream#read
java.io.DataInputStream#readByte
sun.rmi.transport.StreamRemoteCall#executeCall
sun.rmi.server.UnicastRef#invoke
java.rmi.server.RemoteObjectInvocationHandler#invokeRemoteMethod
java.rmi.server.RemoteObjectInvocationHandler#invoke
com.sun.proxy.$Proxy19#rrunTest
org.apache.jmeter.engine.ClientJMeterEngine#runTest at line:149
org.apache.jmeter.engine.DistributedRunner#start at line:132
org.apache.jmeter.engine.DistributedRunner#start at line:149
org.apache.jmeter.JMeter#runNonGui at line:1005
org.apache.jmeter.JMeter#startNonGui at line:910
org.apache.jmeter.JMeter#start at line:538
sun.reflect.NativeMethodAccessorImpl#invoke0
sun.reflect.NativeMethodAccessorImpl#invoke
sun.reflect.DelegatingMethodAccessorImpl#invoke
java.lang.reflect.Method#invoke
org.apache.jmeter.NewDriver#main at line:248

【问题讨论】:

  • 你能写一个小的、独立的程序来重现这个问题吗?如果您在此处发布它,它将帮助其他人调查问题。请参阅minimal reproducible example 上的帮助。

标签: jmeter jvm performance-testing load-testing distributed


【解决方案1】:

我强烈推荐使用这个 jmeter 属性:

jmeterengine.force.system.exit=true

记录在here。这些中文网页linklink给了我提示。

您可以在启动JMeter时在命令行中添加-Jjmeterengine.force.system.exit=true,或者在JMETER_HOME/bin/jmeter.properties中添加jmeterengine.force.system.exit=true

我如何确认此修复

在 MS-Win10 上使用 JMeter 5.1 和 java 版本“1.8.0_231”,我们正在使用此 JMeter InfluxDB backend Listener 的自定义版本。 在我从命令行(jmeter.bat -n -t plan.jtl)运行 60 秒后,命令行在显示此输出后挂起(非常类似于 op):

Tidying up ...    @ Wed Jan 29 14:41:04 CST 2020 (1580330464874)
... end of run
The JVM should have exited but did not.
The following non-daemon threads are still running (DestroyJavaVM is OK):
Thread[DestroyJavaVM,5,main], stackTrace:
Thread[pool-2-thread-3,5,main], stackTrace:sun.misc.Unsafe#park
java.util.concurrent.locks.LockSupport#parkNanos
java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject#awaitNanos
java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue#take
java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue#take
java.util.concurrent.ThreadPoolExecutor#getTask
java.util.concurrent.ThreadPoolExecutor#runWorker
java.util.concurrent.ThreadPoolExecutor$Worker#run
java.lang.Thread#run

Thread[pool-2-thread-4,5,main], stackTrace:sun.misc.Unsafe#park
java.util.concurrent.locks.LockSupport#parkNanos
java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject#awaitNanos
java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue#take
java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue#take
java.util.concurrent.ThreadPoolExecutor#getTask
java.util.concurrent.ThreadPoolExecutor#runWorker
java.util.concurrent.ThreadPoolExecutor$Worker#run
java.lang.Thread#run

Thread[pool-2-thread-1,5,main], stackTrace:sun.misc.Unsafe#park
java.util.concurrent.locks.LockSupport#parkNanos
java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject#awaitNanos
java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue#take
java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue#take
java.util.concurrent.ThreadPoolExecutor#getTask
java.util.concurrent.ThreadPoolExecutor#runWorker
java.util.concurrent.ThreadPoolExecutor$Worker#run
java.lang.Thread#run

如下修改我的命令行后,jmeter.bat 干净地退出而不是挂起,所有丑陋的堆栈跟踪也消失了:

jmeter.bat -n -Jjmeterengine.force.system.exit=true -t plan.jtl 

为了确认问题是由我们自定义的JMeter InfluxDB backend Listener 引起的,我从 .jmx 中删除了它,并且还删除了 jmeterengine.force.system.exit=true。没有挂起,没有丑陋的堆栈跟踪(我真的很喜欢堆栈跟踪)。

我还没有采取下一步措施来确定问题出在官方JMeter InfluxDB backend Listener 还是我们定制的变体,它不(也永远不会)公开提供。

应该提到这个故事中的一个空白。我觉得这个测试最终指向了我们定制的后端侦听器(或 jmeter)。然而,奇怪的是,上述线程转储中的线程似乎都不属于后端侦听器。因此,我赞赏 JMeter 通过转储堆栈跟踪做了正确的事情——在适合进行故障排除时,很少有其他应用程序会达到自动转储的程度。但在这种情况下,可能需要增强 jmeter 自动转储代码,因为它没有指向罪魁祸首后端侦听器代码。 Apache 那边有人在听这个吗?

祝你好运。

【讨论】:

  • 你拯救了我的一天。非常感谢:-)
【解决方案2】:

很可能您的 JMeter 引擎已超载,因此当您请求它们时无法正常关闭正在运行的线程。

  1. 确保您关注JMeter Best Practices
  2. 第一个“最佳实践”声明Always use latest version of JMeter,因此请考虑迁移到JMeter 5.0JMeter Downloads 页面上提供的任何最新版本
  3. 确保您的 JMeter 实例在 CPU、RAM 等方面有足够的运行空间。如果您没有其他监控软件,您可以使用JMeter PerfMon Plugin
  4. 获取thread dump 并检查它 - 这样您就可以知道您的测试卡在哪里了
  5. HTTP Request Defaults 中引入合理的超时值,以便在服务器无法响应时,JMeter 不会无限等待,而是会因错误而失败

  6. 最后(但我不建议这样做)您可以 suppress this check 将下一行添加到 user.properties 文件:

    jmeter.exit.check.pause=-1
    

    如果您这样做,请记住,您可能会遇到这样的情况:即使在您的测试结束后,JMeter 从站仍会尝试执行某些操作,因此您需要手动或使用脚本终止并重新启动进程。

【讨论】:

  • @DT,对于#6 jmeter.exit.check.pause=-1,在分布式模式下,此属性应仅在主服务器上设置,或者在主从服务器上设置。
猜你喜欢
  • 1970-01-01
  • 2013-03-11
  • 2015-12-19
  • 2014-10-23
  • 1970-01-01
  • 1970-01-01
  • 2023-01-17
相关资源
最近更新 更多