gpt4 book ai didi

Java readObject from Inputstream 占用CPU 50%

转载 作者:行者123 更新时间:2023-11-29 05:58:55 25 4
gpt4 key购买 nike

我遇到了一个奇怪的问题,这个线程从输入流读取,特别是 readObject。线程像预期的那样阻塞调用,因为我已经尝试放置日志调试语句并且它显示了它的阻塞。问题是这个线程在分析器中仍然被标记为正在运行,它占用了我 50% 的 cpu 使用率。我有一个与此类似的线程,它正确地阻塞并且阻塞时占用 0% cpu。我对这里可能出现的问题感到困惑。

由于我是新用户,我无法发布图片,请参阅。图中绿色代表奔跑,黄色代表阻挡或等待。

http://i.imgur.com/5FPyZ.png图片也可提供未缩放的 here :

主要

  {
SocketFactory factory = SocketFactory.getDefault();
Socket tcpSocket = factory.createSocket("localhost", 5011);
IoTcpReadRunnable ioTcpReadRunnable = new IoTcpReadRunnable(new MessageProcessor()
{
@Override
public void enqueueReceivedMessage(Object message)
{
System.out.println("MessageReceived Enqueued.");
}

@Override
public void enqueueMessageToWrite(Envelope message)
{
System.out.println("Message Enqueued to Write.");
}
}, tcpSocket);

new Thread(ioTcpReadRunnable, "ClientExample IoTcpRead").start();

TcpRead 可运行

public final class IoTcpReadRunnable implements Runnable {
public static final Logger logger = LoggerFactory.getLogger(IoTcpReadRunnable.class);
protected MessageProcessor<MessageType> messageProcessor = null;
protected Socket tcpSocket = null;
protected ObjectOutputStream outputStream = null;
protected ObjectInputStream inputStream = null;
protected boolean connected = false;

public IoTcpReadRunnable(MessageProcessor<MessageType> messageProcessor, Socket tcpSocket)
{
this.messageProcessor = messageProcessor;
this.tcpSocket = tcpSocket;
this.init();
}

protected void init()
{
try
{
this.outputStream = new ObjectOutputStream(tcpSocket.getOutputStream());
this.outputStream.flush();

this.inputStream = new ObjectInputStream(tcpSocket.getInputStream());
}
catch (IOException ex)
{
logger.error("Tcp Socket Init Error Error ", ex);
}

}

public boolean isConnected()
{
return connected;
}

protected synchronized Object readObject() throws IOException, ClassNotFoundException
{
Object readObject = null;
//blocks here
logger.trace("{} About to block for read Object");

readObject = this.inputStream.readObject();
logger.trace("{} Read Object from Stream: {} ", "", readObject);

return readObject;
}

public void close()
{
try
{
//todo
this.connected = false;
this.outputStream.flush();
this.outputStream.close();
this.inputStream.close();
synchronized (tcpSocket)
{
this.tcpSocket.close();
}
}
catch (IOException ex)
{
logger.error("Error closing Socket");
}
}

@Override
public void run()
{

this.connected = true;

while (this.connected)
{
try
{
Object readObject = readObject();

if (readObject != null)
{
this.messageProcessor.enqueueReceivedMessage((MessageType) readObject);
}
else
{
logger.error("Read Object is null");
}
}
catch (IOException ex)
{
logger.error("TcpRecieveThread IOException", ex);
}
catch (ClassNotFoundException ex)
{
logger.error("TcpRecieveThread ClassnotFound", ex);
}
}
this.close();

}
}

最佳答案

  1. 分析它。这可能会告诉您很多信息。

  2. 是的 - 使用 Java ObjectIOStreams 序列化和反序列化对象是相对 CPU 密集型的。

  3. 您似乎没有在 IO 管道中使用 BufferedInputStream/BufferedOutputStream,因此很可能一次读取和写入一个字节的数据。这可能会显着增加您的 CPU 使用率。


I am saying this thread should be blocked and taking up 0% of cpu when ReadObject is called.

我认为您从根本上误解了一般 I/O 和 readObject 的具体工作方式。当您调用该方法时,它会进行一次(或可能多次)系统调用以从套接字中获取字节。然后,它解码这些字节以找出需要创建的对象,然后创建并初始化它们。所有这些工作都占用 CPU 时间,这些时间被计为“用户时间”或“系统时间”。 CPU 未被计入进程的唯一时间是/如果 read 系统调用必须等待网络数据包到达。

我也不相信那些“剖析”结果。首先,直接阅读您的代码会说 main 方法创建一个新线程,启动它然后立即返回。然而,这些结果似乎表明“主”线程正在连续运行。这是荒谬的……并且会让人怀疑您用来进行分析的方法和/或您向我们解释它们的方式。


还有一件事要检查。你看过日志文件了吗?日志配置是否正确?

关于Java readObject from Inputstream 占用CPU 50%,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10925310/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com