Метод по умолчанию возвращает true на некоторое время, а затем возвращает false? (Возможная ошибка JVM)


у меня проблема со следующим кодом, который я выделил в самой закрытой форме, я использую Java 8, который почти готов к запуску (18 марта 2014 года), поэтому я не ожидаю серьезных проблем в самой реализации, поэтому это может/должен быть мой собственный код:

Примечание: код написан на 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=true / R=true
изолированный Жук.Box@5acf9800 C=true / R=true
изолированный Жук.Box@5acf9800 C=true / R=true
изолированный Жук.Box@5acf9800 C=true / R=true
изолированный Жук.Box@5acf9800 C=false / R=false
изолированный Жук.Box@5acf9800 C=false / R=false
изолированный Жук.Box@5acf9800 C=false / R=false
изолированный Жук.Box@5acf9800 C=false / R=false
изолированный Жук.Box@5acf9800 C=false / R=false
изолированный Жук.Box@5acf9800 C=false / R=false

время, когда он переключается с true до false, похоже, зависит от количества вызовов метода, так как при более длительном спящем режиме между ними требуется больше времени для переключения.

я запускаю это, для получения полной информации о Windows 8 64-бит, с as java -version:

java версия "1.8.0"
Java (TM) SE Runtime Environment (build 1.8.0-b129)
Java HotSpot (TM) 64-разрядная серверная виртуальная машина (сборка 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 FilesJavajdk1.8.0jrebin
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:UsersFrankDropboxNetbeansProjec...
java.runtime.version=1.8.0-b129
java.awt.graphicsenv=sun.awt.Win32GraphicsEnvironment
java.endorsed.dirs=C:Program FilesJavajdk1.8.0jreli...
os.arch=amd64
java.io.tmpdir=C:UsersFrankAppDataLocalTemp
line.separator=

java.vm.specification.vendor=Oracle Corporation
user.variant=
os.name=Windows 8.1
sun.jnu.encoding=Cp1252
java.library.path=C:Program FilesJavajdk1.8.0bin;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:UsersFrank
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:UsersFrankDropboxNetbeansProjec...
java.vm.specification.version=1.8
sun.arch.data.model=64
java.home=C:Program FilesJavajdk1.8.0jre
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 FilesJavajdk1.8.0jreli...
sun.boot.class.path=C:Program FilesJavajdk1.8.0jreli...
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

1 65

1 ответ:

Это известная ошибка в Java8.

смотрите эту Джиру:CHA игнорирует методы по умолчанию во время анализа, что приводит к неправильной генерации кода

эта запись в блоге является Просветляющей....

Обновление / Резюме:


Предыдущие Заметки

я воспроизвел эту проблему с:

утверждения о том, что эта проблема решена в b127, сбивают с толку, так как я ясно вижу ее в b129 (если только я не смущен Конвенций версию виртуальной машины...)

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>

Добавить Системы.из.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
}