JVM应该已经退出但没有退出

时间:2018-10-25 10:31:41

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

在非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

2 个答案:

答案 0 :(得分:3)

我强烈建议使用以下jmeter属性:

<?php
  if ($_SERVER["REQUEST_METHOD"] === "POST"){

    // 1. Connect to database.
    $dbhost = "localhost";
    $dbuser = "yourUsername";
    $dbpass = "yourPassword";
    $dbname = "yourDatabase";
    try {
      $connection = new PDO("mysql:host=$dbhost; dbname=$dbname; charset=utf8", $dbuser, $dbpass);
      $connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
      echo "Connected to database successfully!"; 

      // 2. Prepare your statement with placeholders.
      $pdo = $connection->prepare("INSERT INTO theTableName (theColumnName1, theColumnName2) "
        + "VALUES (:placeholderForColumn1value, :placeholderForColumn2value)");

      // 3. Execute your statement with actual values.
      $pdo->execute([
        ":placeholderForColumn1value" => $_POST["actualValue1"],
        ":placeholderForColumn2value" => $_POST["actualValue2"]
      ]);

      // 4. Close your connection to the database.
      $connection = null;

    } catch(PDOException $e) {
      echo "Failed to connect to database: " . $e->getMessage() . ".";
    }
  }
?>

已记录here。这些中文网页link link告诉了我。

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

我如何确认此修复程序

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

jmeterengine.force.system.exit=true

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

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 InfluxDB backend Listener引起的,我从.jmx中删除了该问题,还删除了jmeterengine.force.system.exit = true。没有挂起,没有丑陋的堆栈跟踪(我实际上喜欢堆栈跟踪)。

我尚未采取下一步措施来确定问题出在官方JMeter InfluxDB backend Listener还是我们定制的变体上,而该变体是(永远不会)公开发布的。

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

祝你好运。

答案 1 :(得分:1)

您的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不会无限等待而是会因错误而失败

    JMeter HTTP Request Defaults

  6. 最后(尽管我不建议这样做),您可以通过将下一行添加到 user.properties 文件中来suppress this check

    jmeter.exit.check.pause=-1
    

    如果要这样做,请记住,即使测试结束后,JMeter从站仍会尝试执行某些操作,因此您将需要手动或使用脚本终止并重新启动进程。 / p>