Java 错误JDK-8191002不清楚是编程错误还是JRE错误

Java 错误JDK-8191002不清楚是编程错误还是JRE错误,java,garbage-collection,thread-safety,finalize,Java,Garbage Collection,Thread Safety,Finalize,关于JDK-8191002中描述的问题,也在以下章节中讨论: 我不清楚finalize()方法中array.fill()的用法是正确的还是错误。一些答案建议应该使用可达性功能,但这是否意味着它是一个bug,或者这是否意味着可达性功能是一个解决VM中bug的方法? 谁能澄清/评论 复制自:“此外,该对象字段的预终结读取都不会看到在该对象终结启动后发生的写入。” 这表明JDK-8191002中OtherInstanceFinalizer为NewlyAllocateDarrayFilled编写的代码是

关于JDK-8191002中描述的问题,也在以下章节中讨论: 我不清楚finalize()方法中array.fill()的用法是正确的还是错误。一些答案建议应该使用可达性功能,但这是否意味着它是一个bug,或者这是否意味着可达性功能是一个解决VM中bug的方法? 谁能澄清/评论

复制自:“此外,该对象字段的预终结读取都不会看到在该对象终结启动后发生的写入。”
这表明JDK-8191002中OtherInstanceFinalizer为NewlyAllocateDarrayFilled编写的代码是正确的,并且故障是由JVM造成的。还是不

简而言之,这是Java代码中的错误,而不是JVM中的错误

此代码模式已在中抽象为

其中
getBytes()
可能确实会错误地返回
z
填充的数组,而不是反映原始内容的数组(理论上,它甚至可能返回部分填充的数组)

“读取字段”是指读取数组引用。阵列的克隆(或阵列的任何处理)发生在之后,因此,不会阻止字段所有者被垃圾收集

由于没有强制执行线程间内存可见性的操作,因此实际上甚至不需要“读取字段”,线程可以重用以前读取的值(此处仍在谈论引用的值),从而允许更早地收集对象。如果终结器更改了引用,这仍然符合不感知终结器对字段的写入的要求

如上所述,这并没有说明数组的内容,因为它不是被垃圾收集的数组。数组和包含数组引用的对象是两个完全不同的对象

在克隆阵列后,在holder上放置一个可达性围栏会创建一个新的依赖项,而该依赖项并不存在,因为在克隆阵列完成之前,无法收集阵列holder

byte[] getBytes() { 
    byte[] result = _bytes.clone(); 
    Reference.reachabilityFence(this); 
    return result; 
}
没有它,对对象的最后一次访问是在调用
clone()
之前,但是如上所述,通过重用以前读取的引用,该访问可能会得到优化。如JLS§12.6.1所述:

可以设计程序的优化转换,以减少可访问对象的数量,使其少于天真地认为可访问的对象的数量


谢谢,解释清楚。Imho JDK-8191002应该被拒绝(而不是“重复”),但好的,这是另一个讨论。
byte[] getBytes() { 
    byte[] result = _bytes.clone(); 
    Reference.reachabilityFence(this); 
    return result; 
}