JVM应该已经退出但未退出

6

在非GUI模式下使用JMeter 3.3进行分布式测试时,我遇到错误如下,该怎么解决:

我在主机和从机上都使用了相同版本的JMeter和JDK。

JVM应该已经退出但没有退出。 以下非守护线程仍在运行(DestroyJavaVM是OK的): Thread [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

你能否编写一个小的、自包含的程序来重现这个问题?如果你在这里发布它,将有助于其他人调查问题。请参阅[mcve]上的帮助。 - akraf
2个回答

11

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

jmeterengine.force.system.exit=true

在这里记录此处。这些中文网页链接 链接 给了我提示。

当启动JMeter时,可以在命令行上添加-Jjmeterengine.force.system.exit=true,或者将jmeterengine.force.system.exit=true添加到JMETER_HOME/bin/jmeter.properties文件中。

如何确认此修复程序

使用JMeter 5.1和java版本"1.8.0_231"在MS-Win10上,我们正在使用定制版本的JMeter InfluxDB后端监听器。 在我的60秒测试运行之后从命令行(jmeter.bat -n -t plan.jtl)开始,命令行挂起并显示此输出(与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后端侦听器引起,我将其从.jmx中删除,并且也删除了jmeterengine.force.system.exit=true。没有挂起,没有丑陋的堆栈跟踪(实际上我喜欢堆栈跟踪)。
我还没有采取下一步措施来发现问题是与官方JMeter InfluxDB后端侦听器有关还是与我们的定制变体有关,后者不可公开使用。
应该提到这个故事中的一个空缺。我觉得这个测试可以明确指出我们定制的后端侦听器(或者jmeter的)。然而,奇怪的是上面线程转储中似乎没有一个属于后端侦听器。所以我赞扬JMeter做了正确的事情,通过转储堆栈跟踪,很少有其他应用程序像适合故障排除时自动转储那样去做得如此周全。但在这种情况下,也许需要增强jmeter自动转储代码,因为它没有指向罪犯后端侦听器代码。Apache那边有人在听吗?
祝你好运。

2

很可能你的JMeter引擎已经超载,因此当你请求它们停止运行线程时,无法优雅地关闭正在运行的线程。

  1. Make sure you follow JMeter Best Practices
  2. The very first "best practice" states Always use latest version of JMeter so consider migrating to JMeter 5.0 or whatever latest version is available at JMeter Downloads page
  3. Make sure your JMeter instances have enough headroom to operate in terms of CPU, RAM and so on. You can use JMeter PerfMon Plugin for this if you don't have other monitoring software in place/in mind.
  4. Take a thread dump and examine it - this way you will know where exactly your test is stuck
  5. Introduce reasonable timeout values in HTTP Request Defaults so in case when server fails to respond JMeter wouldn't wait infinitely but rather fail with an error

    JMeter HTTP Request Defaults

  6. And finally (however I wouldn't recommend this) you can suppress this check by adding the next line to user.properties file:

    jmeter.exit.check.pause=-1
    

    if you go for this keep in mind that you may run into a situation when JMeter slaves will still be trying to execute something even after your test ends so you will need to kill and restart the processes manually or using a script.


@DT,对于#6 jmeter.exit.check.pause=-1,在分布式模式下,此属性应仅在主节点上设置还是在主节点和从节点上都设置。 - vishalcdac07

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接