Java 8 和垃圾收集

标签 java

我有一个关于 Java 8 和垃圾收集的问题,我们以前在 Java 6 上运行的应用程序遇到问题,现在我们在间歇打印主机发送到应用程序的打印消息时遇到问题,它们大部分时间都在工作,但是根据日志,当打印机消息发送到 PrintSystem 类(作为单独的线程运行)时,它看起来没有响应。在阅读一些有关 GC 以及强引用和弱引用的内容时,PrintSystem 发送消息的方式似乎是这样的

PrintSystem.getInstance().printMessage(消息);

因此,由于 Java 6 和 8 之间的差异,Java 8 有可能对 PrintSystem 线程进行 GC 吗?此外,代码已重新编译以在 Java 8 上运行,我想知道是否仍应为 Java 6 编译并在 Java 8 上运行它(如果有意义的话)

日志数据 07Jan 14:59:38.037 communications.headers.PLMHeader.PLMMessage() INFO userData 为 25 字节

07Jan 14:59:38.038 communications.headers.PLMHeader.PLMMessage() INFO userData 是: 测试消息

07Jan 14:59:38.038 communications.ums.UMSWorker.run() INFO UMS Worker Activity

07Jan 14:59:38.038 communications.ums.UMSWorker.run() INFO 收到未经请求的消息...

07Jan 14:59:38.038 communications.ums.UMSWorker.run() INFO 发送消息到打印系统(从 UMSWorker 线程发送应该有 100 毫秒的 PrintSystem 响应)

2019 年 1 月 7 日 15:00:19.365 communications.ums.UMSWorker.setAceNetHeader() INFO 数据为:(下一条消息前 41 秒及其无关)

public void printMessage(Object message) throws Exception
{
if (!initialized)
   throw new Exception("DEBUG: Print System not initialized!");
try 
{
 synchronized(this)
 {
  printList.add(message); // LinkedList 
  this.notify();
 }
 LogManager.traceMessage(this,"DEBUG: PrintSystem.PrintMessage()", 
"printList Size : " + printList.size());
}
catch (Exception e)
{
 LogManager.traceMessage(this,"DEBUG: PrintSystem.PrintMessage() ", 
 "Exception : " + e);
}
}

这是等待/循环读取 printList 的 PrintSystem run()

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 时,你得到的东西之一就是更好的优化,它可以做一些奇特的事情,比如弄清楚何时可以延迟更新缓存,或者何时可以完全排除必须执行某些代码,以及决定何时调用这些优化必须假设它们所应用的代码是充分同步的。如果代码不是,那么优化可能会以某种不是您想要的方式应用。

关于Java 8 和垃圾收集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54561347/

相关文章:

java - 为什么类不能扩展其中出现的静态嵌套类?

java - Java中的无状态对象是什么?

java - 无法执行目标org.apache.maven.plugins :maven-compiler-plugin:3.1:compile (default-compile) on project [duplicate]

java - 哪个第 3 方 Oracle 数据库 JDBC 驱动程序?

java - 将枚举值转换为逗号分隔字符串的最有效方法

java - 更新 SQL 查询在 Java Swing 中不起作用

java - To_tsvector() inside of bulk COPY FROM STDIN Postgres

java - Kafka 获取偏移数据时出错。原因: 1

java - 使用 Java 登录 SiteMinder

Java:根据字符串的内容创建一个对象