奇怪的JavaFX8 OutOfMemoryError - FadeTransition

Mic*_*rry 4 java memory-leaks javafx fade javafx-8

经过几个小时的尝试追踪我的应用程序中的内存错误,我已经设法在一个简单的JFX程序中将其减少为一些非常奇怪的行为:

采用以下简单示例,逐渐将矩形淡入透明画布:

public class Test extends Application {

    @Override
    public void start(Stage primaryStage) {
        primaryStage.initStyle(StageStyle.TRANSPARENT);
        int width = 1920;
        int height = 1080;

        Rectangle rect = new Rectangle(width, height);
        rect.setFill(Color.SALMON);
        rect.setOpacity(0);
        StackPane scenePane = new StackPane();
        scenePane.getChildren().add(rect);
        primaryStage.setScene(new Scene(scenePane));
        primaryStage.setWidth(width);
        primaryStage.setHeight(height);
        primaryStage.show();
        FadeTransition ft = new FadeTransition(Duration.millis(10000), rect);
        ft.setToValue(1);
        ft.play();
    }

    public static void main(String[] args) {
        launch(args);
    }

}
Run Code Online (Sandbox Code Playgroud)

使用VM args运行时-Xms100m -Xmx100m,这根本不会有任何问题.但是,当我给VM大大增加内存(例如-Xms1000m -Xmx1000m)时,它会很快崩溃:

java.lang.OutOfMemoryError
        at sun.misc.Unsafe.allocateMemory(Native Method)
        at java.nio.DirectByteBuffer.<init>(DirectByteBuffer.java:127)
        at java.nio.ByteBuffer.allocateDirect(ByteBuffer.java:311)
        at com.sun.prism.impl.BufferUtil.newByteBuffer(BufferUtil.java:90)
        at com.sun.prism.impl.BufferUtil.newIntBuffer(BufferUtil.java:121)
        at com.sun.javafx.tk.quantum.UploadingPainter.run(UploadingPainter.java:148)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
        at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308)
        at com.sun.javafx.tk.RenderJob.run(RenderJob.java:58)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at com.sun.javafx.tk.quantum.QuantumRenderer$PipelineRunnable.run(QuantumRenderer.java:125)
        at java.lang.Thread.run(Thread.java:745)
Run Code Online (Sandbox Code Playgroud)

我尝试过的多个探查器显示堆几乎占用了任何已分配的空间 - 但任务管理器中的进程视图显示它在几秒钟内通过所有可用内存进行射击.

该怪事还没有结束但是-似乎只翻倒的一些价值观widthheight(一个width1921例如意味着应用程序执行精细,看不到的错误.)

这似乎只发生在一个透明的阶段.如果没有在第一行的舞台上设置透明样式,一切看起来都很好(无论如何我都尝试了所有配置.)同样,它只发生在Java 8上(我使用的是8u20) - Java 7都可以./JFX 2.x. 我正在运行Windows 7x64.

任何人都可以重现这个问题,任何人都可以对任何可能发生的事情有所了解吗?!这是迄今为止我遇到的最奇怪的事情......

更新:我已经设法在一台单独的Windows 8机器上重现这一点,但是另一台Windows 7机箱(和一台Mac)似乎都很好.我不确定究竟是什么JFX代码路径,但不幸的是它似乎完全依赖于机器.

pie*_*t.t 5

这只回答了你的部分问题,但这就是为什么增加你的堆会导致OutOfMemeoryError:

从堆栈跟踪中可以看出,JavaFX正在使用a DirectByteBuffer进行处理 - 因此数据不会存储在堆中,而是存储在本内存中.通过增加(固定)堆大小,可以减少操作系统可以作为本机内存提供的可用内存量.

例如,在使用32位Java-VM的Windows上,可寻址内存范围为4GB,为操作系统保留2GB,为Java应用程序留出2GB.随着-Xms1000m -Xmx1000m另一GB保留给堆离开1GB的VM代码,栈,非堆内存(如PermGen的等),还剩下些什么他最后GB的可以作为本机内存.