簡體   English   中英

默認方法返回true一段時間,然后返回false? (可能的JVM錯誤)

[英]Default method returns true for a while, and then returns false? (Possible JVM bug)

我有一個問題,下面的代碼,我隔離到最封閉的形式,我使用Java 8,幾乎准備好發布(2014年3月18日),所以我希望在實現本身沒有嚴重的問題,所以它可能/必須是我自己的代碼:

注意:代碼是用Java 8編寫的,它具有各種新功能,包括接口中的default方法實現。

public abstract class Drawable implements DrawableInterface {    

}

interface DrawableInterface {
    default public boolean isShadowReceiver() {
        return false;
    }

    default public boolean isShadowCaster() {
        return false;
    }
}

public interface ShadowDrawable extends DrawableInterface {
    @Override
    default public boolean isShadowReceiver() {
        return true;
    }

    @Override
    default public boolean isShadowCaster() {
        return true;
    }
}

public class Box extends Drawable implements ShadowDrawable {

}

public class IsolatedBug {
    private final Box box;

    private final List<Drawable> drawables;

    public IsolatedBug() {
        this.box = new Box();
        this.drawables = new ArrayList<>();

        drawables.add(box);
        drawables.forEach(drawable -> System.out.println(drawable + " C=" + drawable.isShadowCaster() + "/R=" + drawable.isShadowReceiver()));
    }

    private void init() throws InterruptedException {
        while (true) {
            drawables.forEach(drawable -> System.out.println(drawable + " C=" + drawable.isShadowCaster() + "/R=" + drawable.isShadowReceiver()));
            Thread.sleep(100);
        }
    }

    public static void main(String[] args) throws InterruptedException {
        new IsolatedBug().init();
    }
}

代碼本身可能沒有多大意義,但這是因為我已經剝奪了大量其他不相關的方法。

但是,當你觀察輸出時,你會在某個時刻看到一些奇怪的東西,對於我個人來說,30秒后,我看到以下內容:

isolatedbug.Box@5acf9800 C =真/ R =真
isolatedbug.Box@5acf9800 C =真/ R =真
isolatedbug.Box@5acf9800 C =真/ R =真
isolatedbug.Box@5acf9800 C =真/ R =真
isolatedbug.Box@5acf9800 C = false / R = false
isolatedbug.Box@5acf9800 C = false / R = false
isolatedbug.Box@5acf9800 C = false / R = false
isolatedbug.Box@5acf9800 C = false / R = false
isolatedbug.Box@5acf9800 C = false / R = false
isolatedbug.Box@5acf9800 C = false / R = false

它從true切換到false的時間似乎取決於方法的調用次數,因為在兩者之間休眠時間越長,切換時間就越長。

我正在運行這個,有關Windows 8 64位的完整信息,請使用java -version

java版“1.8.0”
Java(TM)SE運行時環境(版本1.8.0-b129)
Java HotSpot(TM)64位服務器VM(內置25.0-b69,混合模式)

任何人都可以向我解釋發生了什么事嗎?
我也很感激,如果其他人使用Java 8 -any build-,可以運行,看看他們是否有同樣的問題。

使用此代碼后的更多信息:

  Properties p = System.getProperties();
  p.list(System.out);

輸出:

-- listing properties --
java.runtime.name=Java(TM) SE Runtime Environment
sun.boot.library.path=C:\Program Files\Java\jdk1.8.0\jre\bin
java.vm.version=25.0-b69
java.vm.vendor=Oracle Corporation
java.vendor.url=http://java.oracle.com/
path.separator=;
java.vm.name=Java HotSpot(TM) 64-Bit Server VM
file.encoding.pkg=sun.io
user.script=
user.country=NL
sun.java.launcher=SUN_STANDARD
sun.os.patch.level=
java.vm.specification.name=Java Virtual Machine Specification
user.dir=C:\Users\Frank\Dropbox\NetbeansProjec...
java.runtime.version=1.8.0-b129
java.awt.graphicsenv=sun.awt.Win32GraphicsEnvironment
java.endorsed.dirs=C:\Program Files\Java\jdk1.8.0\jre\li...
os.arch=amd64
java.io.tmpdir=C:\Users\Frank\AppData\Local\Temp\
line.separator=

java.vm.specification.vendor=Oracle Corporation
user.variant=
os.name=Windows 8.1
sun.jnu.encoding=Cp1252
java.library.path=C:\Program Files\Java\jdk1.8.0\bin;C:...
java.specification.name=Java Platform API Specification
java.class.version=52.0
sun.management.compiler=HotSpot 64-Bit Tiered Compilers
os.version=6.3
user.home=C:\Users\Frank
user.timezone=
java.awt.printerjob=sun.awt.windows.WPrinterJob
file.encoding=UTF-8
java.specification.version=1.8
user.name=Beheerder
java.class.path=C:\Users\Frank\Dropbox\NetbeansProjec...
java.vm.specification.version=1.8
sun.arch.data.model=64
java.home=C:\Program Files\Java\jdk1.8.0\jre
sun.java.command=isolatedbug.IsolatedBug
java.specification.vendor=Oracle Corporation
user.language=nl
awt.toolkit=sun.awt.windows.WToolkit
java.vm.info=mixed mode
java.version=1.8.0
java.ext.dirs=C:\Program Files\Java\jdk1.8.0\jre\li...
sun.boot.class.path=C:\Program Files\Java\jdk1.8.0\jre\li...
java.vendor=Oracle Corporation
file.separator=\
java.vendor.url.bug=http://bugreport.sun.com/bugreport/
sun.cpu.endian=little
sun.io.unicode.encoding=UnicodeLittle
sun.desktop=windows
sun.cpu.isalist=amd64

我還檢查了-Xint VM選項,當使用它時,它會按預期返回true

所以結論似乎是在我的特定用例中,代碼的解釋和JIT編譯/內聯變體是不一樣的,因此在編譯解釋的代碼之后它有可能從解釋代碼切換到編譯,從而澄清輸出開關。

-Xint選項添加到發生錯誤的實際程序中,也解決了問題。

官方錯誤報告已被接受: JIRA Bug JDK-8036100

這是Java8中的已知錯誤。

請參閱此Jira: CHA在分析過程中忽略默認方法,導致代碼生成錯誤

這篇博客文章很有啟發性 ......

更新/摘要:


以前的注釋

我轉載了這個問題:

聲稱在b127中解決了這個問題令人困惑,因為我在b129中清楚地看到它(除非我對JVM版本約定感到困惑......)

 C:\\Java8\\jdk-1.8.0_01\\bin>java -version java version "1.8.0" Java(TM) SE Runtime Environment (build 1.8.0-b129) Java HotSpot(TM) 64-Bit Server VM (build 25.0-b69, mixed mode) C:\\Java8\\jdk-1.8.0_01\\bin> 

添加System.out.println(System.getProperties());

 { java.runtime.name=Java(TM) SE Runtime Environment, java.runtime.version=1.8.0-b129, java.vm.specification.name=Java Virtual Machine Specification, java.vm.name=Java HotSpot(TM) 64-Bit Server VM, java.vm.version=25.0-b69, java.vm.vendor=Oracle Corporation, java.vendor.url=http://java.oracle.com/, java.vm.specification.version=1.8, java.specification.name=Java Platform API Specification, java.specification.version=1.8, java.specification.vendor=Oracle Corporation, java.class.version=52.0, sun.boot.library.path=C:\\Java8\\jdk-1.8.0_01\\jre\\bin, sun.java.launcher=SUN_STANDARD, sun.os.patch.level=Service Pack 1, java.endorsed.dirs=C:\\Java8\\jdk-1.8.0_01\\jre\\lib\\endorsed, os.arch=amd64, java.vm.specification.vendor=Oracle Corporation, os.name=Windows 7, sun.jnu.encoding=Cp1252, java.library.path=C:\\Java8\\jdk-1.8.0_01\\bin;......, sun.management.compiler=HotSpot 64-Bit Tiered Compilers, os.version=6.1, file.encoding=UTF-8, sun.java.command=fromso.IsolatedBug, java.home=C:\\Java8\\jdk-1.8.0_01\\jre, sun.arch.data.model=64, user.language=en, java.ext.dirs=C:\\Java8\\jdk-1.8.0_01\\jre\\lib\\ext;C:\\windows\\Sun\\Java\\lib\\ext, sun.boot.class.path=C:\\Java8\\jdk-1.8.0_01\\jre\\lib\\resources.jar;......, java.vendor=Oracle Corporation, file.separator=\\, java.vendor.url.bug=http://bugreport.sun.com/bugreport/, sun.io.unicode.encoding=UnicodeLittle, sun.cpu.endian=little, sun.desktop=windows, sun.cpu.isalist=amd64 } 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM