为什么我的进程挂在input.readLine()?

时间:2013-10-07 12:34:28

标签: java jmeter

我有一个实用程序,Jmeter发送请求,实用程序将响应发送回Jmeter。当负载增加时,Utility将以“EXCEPTION_ACCESS_VIOLATION”关闭。

由于这是一个错误,我无法在catch块中处理它。我做了第二个实用程序,在错误发生时重新启动第一个实用程序。下面是第二个,重启,实用程序的代码。在第二个实用程序的代码中,在时,我的程序有时会挂起。如何检测并重启该过程?

public static void main(String[] args)
{
    String line = null;
    String currPID = null;
    try
    {
        while(true)
        {
            Process process = Runtime.getRuntime().exec("java -XX:+HeapDumpOnOutOfMemoryError -Xms250M -Xmx500M -XX:ErrorFile=NUL ws ");
            BufferedReader input = new BufferedReader(new InputStreamReader(process.getInputStream()));
            while ((line = input.readLine()) != null) //Program stucks at this Line
            {
                if(line.trim().length() != 0)
                {
                    if(line.startsWith("PID"))
                    {
                        currPID = line.substring(line.indexOf("@")+1);
                    }
                }
            }
            System.out.println("Ended");
        }
    }
    catch(Exception e)
    {
        e.printStackTrace();
    }
}

我通过jvisualvm分析了进程,当我启动第二个(重新启动)实用程序时,我发现两个java进程处于运行模式。我可以看到第一个实用程序正在重新启动,因为它的PID在jvisualvm中频繁更改,并且在任务管理器中也是如此。一切都很顺利。

过了一段时间后,我发现只有一个进程在Jvisualvm中,即第二个(重启)实用程序。 这意味着第一个实用程序JVM崩溃只是猜测不确定。这里发生了一些不寻常的事情。因为如果JVM崩溃所以应该重新启动它。 所以我打开了任务管理器,发现第一个实用程序PID存在,但它没有像开始时那样发生变化。如果我从任务管理器明确地杀死进程(第一个实用程序)。 Seconds实用程序再次重启第一个实用程序同样的事情再次发生,经过一段时间后第一个实用程序从jvisualvm消失,存在于taskmanager中并从taskmanager中删除进程。需要做什么?

3 个答案:

答案 0 :(得分:2)

尝试使用.ready()函数。

try {
      if (stdError.ready()) 
      {
            while((line= stdError.readLine()) != null){
                logger.error(line);
            }
      }
}

对stdout执行相同的操作。

它对我来说就像一个魅力。

答案 1 :(得分:1)

您的悬挂问题似乎在调用readLine

readLine用于阅读行。在调用确定已到达行尾之前,该方法不会返回。它期望换行符或完全停止通信。

您的第一个实用程序是否未发送新行char?

您的第一个实用程序是否无法关闭流?

如果两个问题的答案都是肯定的,那么您的同时通话将无限期挂起。

使用Scanner类的自定义实现可能会更好。

答案 2 :(得分:1)

尝试使用getErrorStream()它会捕获错误消息,如果您使用getInputStream()它只会读取成功消息或反馈消息。

例如:如果你执行以下命令&使用getInputStream()

阅读流程消息
Process process = Runtime.getRuntime().exec("net use u: \\sharedIP\sharedFolder");
BufferedReader input = new BufferedReader(new inputStreamReader(process.getInputStream()));

您只能获得“网络驱动器已成功连接”等反馈消息,但不会收到错误消息。

如果您使用getErrorStream()来阅读进程消息,它将会读取错误消息,例如“找不到网络驱动器”。当流程执行时,它会向getInputStream()getErrorStream()发送消息。所以使用两种方法从过程中读取消息,如果我是正确的,这将是有效的。我只想给你一个想法,但我不确定。