Java8和垃圾收集
我有一个关于Java 8和垃圾收集的问题,我们有一个应用程序的问题,这个应用程序过去在Java 6上运行时没有问题,现在我们在间歇性打印主机发送给应用程序的打印消息方面遇到了问题。打印消息大部分时间都可以工作,但是根据日志,打印机消息显示时看起来是这样的发送到PrintSystem类(作为单独的线程运行)时,它没有响应。在阅读有关GC和强引用和弱引用的内容时,PrintSystem发送消息的方式似乎是这样的 PrintSystem.getInstance().printMessage(消息) 因此,有可能是由于Java6和Java8之间的差异,Java8正在对PrintSystem线程进行GC?另外,代码被重新编译为针对Java8运行,我想知道它是否仍然应该针对Java6进行编译,并在Java8上运行它(如果这有意义的话) 日志数据 07Jan 14:59:38.037 communications.headers.PLMHeader.PLMMessage()信息用户数据为25字节 07Jan 14:59:38.038 communications.headers.PLMHeader.PLMMessage()信息用户数据为: 测试消息 07Jan 14:59:38.038 communications.ums.UMSWorker.run()信息ums Worker活动 07Jan 14:59:38.038 communications.ums.UMSWorker.run()信息收到未经请求的消息 07Jan 14:59:38.038 communications.ums.UMSWorker.run()信息向打印系统发送消息(从UMSWorker线程发送的打印系统响应应为100ms) 2019年1月7日15:00:19.365 communications.ums.UMSWorker.setAceNetHeader()信息数据为:(下一条消息及其无关消息前41秒) 这是PrintSystem run(),它等待/循环读取打印列表Java8和垃圾收集,java,Java,我有一个关于Java 8和垃圾收集的问题,我们有一个应用程序的问题,这个应用程序过去在Java 6上运行时没有问题,现在我们在间歇性打印主机发送给应用程序的打印消息方面遇到了问题。打印消息大部分时间都可以工作,但是根据日志,打印机消息显示时看起来是这样的发送到PrintSystem类(作为单独的线程运行)时,它没有响应。在阅读有关GC和强引用和弱引用的内容时,PrintSystem发送消息的方式似乎是这样的 PrintSystem.getInstance().printMessage(消息) 因
public void run()
{
Object message = null;
while (true)
{
try
{
synchronized(this)
{
this.wait(2500);
}
}
catch (Exception e) {}
while (!printList.isEmpty())
{
synchronized(this)
{
message = printList.removeFirst();
}
int printed = printPLMMessage((PLMHeader) message);
PLMHeader ackHeader = generatePrinterAck((PLMHeader)
message,printed);
Communications.getInstance().ack(ackHeader);
}
}
谢谢我怀疑这不是GC问题。我认为这是一个有缺陷的代码问题 该代码在printList中添加了一个锁,但是从printList读取的代码在读取时没有锁。这使得该代码没有充分同步,因此无法保证读取线程的printList更新的可见性
很明显,你之前很幸运,这个代码是偶然运行的。当您升级Java时,您得到的其中一件事就是更好的优化,这做了一些奇妙的事情,比如弄清楚它们何时可以延迟更新缓存,或者何时可以完全排除执行某些代码,关于何时调用这些优化的决策必须假设它们应用到的代码已经充分同步。如果代码不是,那么优化可以以某种方式应用,而这不是您想要的 线程是垃圾收集根,不能进行垃圾收集。此外,我认为您必须共享一些代码。请尝试提供一部分(可能是简化的)代码。我将尝试输入一些代码和日志信息,但是线程可以被GC'd这一事实表明线程出现了问题,它可以被锁定吗?或者是什么原因导致它失败。如果代码被重写以在Java 8上工作,那么问题可能是在那里引入的。读取属性文件只有一个小小的更改,否则代码是相同的。感谢Nathan,可能是Java 8只是暴露了代码的一个问题,但仍然需要回答这个问题(可能已经)是打印列表(LinkedList)不同步会导致线程挂起或失败,需要应用程序循环。我可以看到不同步会导致数据不准确,但线程应该会响应,我认为?@Dan:还有一个问题是通知丢失,因为wait and notify如何不使用条件变量。可能会尝试使用Ar重写rayBlockingQueue。谢谢Nathan,当前等待有一个超时,因此它将每2.5秒检查一次。我将查看ArrayBlockingQueue
public void run()
{
Object message = null;
while (true)
{
try
{
synchronized(this)
{
this.wait(2500);
}
}
catch (Exception e) {}
while (!printList.isEmpty())
{
synchronized(this)
{
message = printList.removeFirst();
}
int printed = printPLMMessage((PLMHeader) message);
PLMHeader ackHeader = generatePrinterAck((PLMHeader)
message,printed);
Communications.getInstance().ack(ackHeader);
}
}