Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 我的方法是耗尽堆空间。是否需要将某些内容设置为null?_Java_Animation_Javafx - Fatal编程技术网

Java 我的方法是耗尽堆空间。是否需要将某些内容设置为null?

Java 我的方法是耗尽堆空间。是否需要将某些内容设置为null?,java,animation,javafx,Java,Animation,Javafx,我创建了这个方法来以幻灯片形式显示图像列表。 它工作得很好,直到有超过50或60张图像需要处理。然后它崩溃了,伴随着 java.lang.OutOfMemoryError:java堆空间 所以我想知道我是否应该在每次循环中都将某个值设置为null?我在这里和网上搜索过,但没有找到答案 方法如下: private void createSlideshow(Stage stage, ArrayList<BufferedImage> slideList, int durationInSec

我创建了这个方法来以幻灯片形式显示图像列表。 它工作得很好,直到有超过50或60张图像需要处理。然后它崩溃了,伴随着

java.lang.OutOfMemoryError:java堆空间

所以我想知道我是否应该在每次循环中都将某个值设置为null?我在这里和网上搜索过,但没有找到答案

方法如下:

private void createSlideshow(Stage stage, ArrayList<BufferedImage> slideList, int durationInSecs) throws InterruptedException {

            stage.show();
            SequentialTransition slideshow = new SequentialTransition();
            int i = 0;
            for (BufferedImage bi: slideList) {
                System.out.println(" Iteration " + (i++));
                ImageView slide = new ImageView(SwingFXUtils.toFXImage(bi, null));    // LINE 108
                FadeTransition fadeIn =  new FadeTransition(Duration.millis(durationInSecs * 1000), slide);
                fadeIn.setFromValue(0.0);
                fadeIn.setToValue(1.0);

                PauseTransition stayOn = new PauseTransition(Duration.millis(durationInSecs * 1000));

                FadeTransition fadeOut =  new FadeTransition(Duration.millis(durationInSecs * 1000), slide);
                fadeOut.setFromValue(1.0);
                fadeOut.setToValue(0.0);

                SequentialTransition fadeInOut = new SequentialTransition();
                fadeInOut.getChildren().addAll(fadeIn, stayOn, fadeOut);
                slide.setOpacity(0.0);              
                root.getChildren().add(slide);            
                slideshow.getChildren().add(fadeInOut);
            }
            slideshow.play();
        }
private void createSlideshow(Stage-Stage、ArrayList-slideList、int-durationInSecs)抛出InterruptedException{
stage.show();
SequentialTransition幻灯片放映=新的SequentialTransition();
int i=0;
用于(BuffereImage bi:slideList){
System.out.println(“迭代”+(i++);
ImageView幻灯片=新的ImageView(SwingFXUtils.toFXImage(bi,null));//第108行
FadeTransition fadeIn=新的FadeTransition(持续时间.millis(持续时间*1000),幻灯片);
fadeIn.setFromValue(0.0);
fadeIn.setToValue(1.0);
PauseTransition station=新的PauseTransition(持续时间.millis(持续时间*1000));
FadeTransition fadeOut=新的FadeTransition(持续时间.millis(持续时间*1000),幻灯片);
衰减。设置自值(1.0);
衰减设置值(0.0);
SequentialTransition fadeInOut=新的SequentialTransition();
fadeInOut.getChildren().addAll(fadeIn、stayOn、fadeOut);
幻灯片。设置不透明度(0.0);
root.getChildren().add(幻灯片);
slideshow.getChildren().add(fadeInOut);
}
slideshow.play();
}
完整的运行时消息如下所示:

Exception in Application start method
java.lang.reflect.InvocationTargetException
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(Unknown Source)
        at com.sun.javafx.application.LauncherImpl.launchApplication(Unknown Source)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at sun.launcher.LauncherHelper$FXHelper.main(Unknown Source)
Caused by: java.lang.RuntimeException: Exception in Application start method
        at com.sun.javafx.application.LauncherImpl.launchApplication1(Unknown Source)
        at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$155(Unknown Source)
        at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.OutOfMemoryError: Java heap space
        at java.nio.HeapByteBuffer.<init>(Unknown Source)
        at java.nio.ByteBuffer.allocate(Unknown Source)
        at com.sun.javafx.tk.quantum.QuantumToolkit.createPlatformImage(Unknown Source)
        at javafx.scene.image.Image.<init>(Unknown Source)
        at javafx.scene.image.WritableImage.<init>(Unknown Source)
        at javafx.embed.swing.SwingFXUtils.toFXImage(Unknown Source)
        at Slideshow.createSlideshow(Slideshow.java:108)
        at Slideshow.start(Slideshow.java:52)
        at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$162(Unknown Source)
        at com.sun.javafx.application.LauncherImpl$$Lambda$64/1581649247.run(Unknown Source)
        at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$175(Unknown Source)
        at com.sun.javafx.application.PlatformImpl$$Lambda$49/1915503092.run(Unknown Source)
        at com.sun.javafx.application.PlatformImpl.lambda$null$173(Unknown Source)
        at com.sun.javafx.application.PlatformImpl$$Lambda$51/1557268138.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at com.sun.javafx.application.PlatformImpl.lambda$runLater$174(Unknown Source)
        at com.sun.javafx.application.PlatformImpl$$Lambda$50/1567581361.run(Unknown Source)
        at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(Unknown Source)
        at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
        at com.sun.glass.ui.win.WinApplication.lambda$null$148(Unknown Source)
        at com.sun.glass.ui.win.WinApplication$$Lambda$39/1645995473.run(Unknown Source)
        ... 1 more
Exception running application Slideshow
应用程序启动方法中出现异常 java.lang.reflect.InvocationTargetException 在sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)处 位于sun.reflect.NativeMethodAccessorImpl.invoke(未知源) 在sun.reflect.DelegatingMethodAccessorImpl.invoke处(未知源) 位于java.lang.reflect.Method.invoke(未知源) 位于com.sun.javafx.application.LaunchImpl.launchApplicationWithArgs(未知源) 位于com.sun.javafx.application.LaunchImpl.launchApplication(未知源) 在sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)处 位于sun.reflect.NativeMethodAccessorImpl.invoke(未知源) 在sun.reflect.DelegatingMethodAccessorImpl.invoke处(未知源) 位于java.lang.reflect.Method.invoke(未知源) 位于sun.launcher.launchelper$FXHelper.main(未知源) 原因:java.lang.RuntimeException:应用程序启动方法中的异常 位于com.sun.javafx.application.LaunchImpl.launchApplication1(未知源) 位于com.sun.javafx.application.launchempl.lambda$launchApplication$155(未知来源) 位于java.lang.Thread.run(未知源) 原因:java.lang.OutOfMemoryError:java堆空间 位于java.nio.HeapByteBuffer。(未知源) 位于java.nio.ByteBuffer.allocate(未知源) 在com.sun.javafx.tk.quantum.QuantumToolkit.createPlatformImage(未知源) 在javafx.scene.image.image。(未知源) 位于javafx.scene.image.WritableImage。(未知源) 位于javafx.embed.swing.SwingFXUtils.toFXImage(未知源) 在Slideshow.createSlideshow(Slideshow.java:108)中 在Slideshow.start(Slideshow.java:52) 位于com.sun.javafx.application.launchempl.lambda$launchApplication1$162(未知来源) 位于com.sun.javafx.application.launchempl$$Lambda$64/1581649247.run(未知源) com.sun.javafx.application.PlatformImpl.lambda$runAndWait$175(未知来源) 位于com.sun.javafx.application.PlatformImpl$$Lambda$49/1915503092.run(未知来源) 位于com.sun.javafx.application.PlatformImpl.lambda$null$173(未知来源) 位于com.sun.javafx.application.PlatformImpl$$Lambda$51/1557268138.run(未知源) 位于java.security.AccessController.doPrivileged(本机方法) com.sun.javafx.application.PlatformImpl.lambda$runLater$174(未知来源) 位于com.sun.javafx.application.PlatformImpl$$Lambda$50/1567581361.run(未知来源) 在com.sun.glass.ui.InvokeLaterDispatcher$Future.run(未知源) 在com.sun.glass.ui.win.WinApplication.\u runLoop(本机方法) 在com.sun.glass.ui.win.WinApplication.lambda$null$148(未知来源) 在com.sun.glass.ui.win.WinApplication$$Lambda$39/1645995473.run(未知来源) ... 还有一个 运行应用程序幻灯片时出现异常
您的主
顺序转换
正在加载所有图像,并在开始播放之前保留对它们的引用。因此,这种技术不会随着图像数量的增加而扩展(这意味着,如果您有足够的图像,就一定会耗尽堆空间)

如果您的图像从
BufferedImage
s合理快速地转换为FX
Image
s,您可以使用时间线来执行此操作:

private void createSlideshow(Stage stage, ArrayList<BufferedImage> slideList, int durationInSecs) throws InterruptedException {

    stage.show();
    Timeline slideshow = new Timeline();

    ImageView slide = new ImageView();

    for (int i = 0; i < slideList.size(); i++) {
        BufferedImage bi = slideList.get(i);
        KeyFrame newImageFrame = new KeyFrame(Duration.seconds(durationInSeconds * 3 * i), e -> 
            slide.setImage(SwingFXUtils.toFXImage(bi, null)));

        KeyFrame startFadeIn = new KeyFrame(Duration.seconds(durationInSeconds * 3 * i), 
            new KeyValue(slide.opacityProperty(), 0));

        KeyFrame endFadeIn = new KeyFrame(Duration.seconds(durationsInSeconds * (3 * i + 1)), 
            new KeyValue(slide.opacityProperty(), 1));

        KeyFrame startFadeOut = new KeyFrame(Duration.seconds(durationInSeconds * (3 * i + 2)), 
            new KeyValue(slide.opacityProperty(), 1));

        slideshow.getKeyFrames().addAll(newImageFrame, startFadeIn, endFadeIn, startFadeOut);

    }
    slideshow.play();
}

最后请注意,您的原始代码以及这两种实现都希望将
buffereImage
s列表传递给该方法。这已经消耗了大量内存:在进入方法体之前,您基本上将所有图像都保存在内存中。根据这些图像的来源,例如,您可以传递
文件
对象的列表,并在此处使用相同的技术根据需要动态加载每个图像(或创建一个小的图像队列,如第二个示例所示)。这实际上可以扩展到任意数量的图像。

可能您没有足够的堆来容纳正在加载的图像。注意:执行此操作时,图像将被解压缩,因此将使用其完全未压缩的大小。e、 g.一张200万像素的图像可能会使用8MB的32位彩色图像,如果
private void createSlideshow(Stage stage, ArrayList<BufferedImage> slideList, int durationInSecs) throws InterruptedException {

    stage.show();

    int numImages = slideList.size();

    BlockingQueue<Image> images = new ArrayBlockingQueue<>(3);

    Thread conversionThread = new Thread(() -> {
        for (BufferedImage bi : slideList) {
            try {
                images.put(SwingFXUtils.toFXImage(bi, null));
            } catch (InterruptedException exc) {
                Thread.currentThread().interrupt();
            }
        }
    });
    conversionThread.setDaemon(true);
    conversionThread.start();

    Timeline slideshow = new Timeline();

    ImageView slide = new ImageView();

    for (int i = 0; i < slideList.size(); i++) {

        KeyFrame newImageFrame = new KeyFrame(Duration.seconds(durationInSeconds * 3 * i), e -> 
            slide.setImage(images.poll())); 

        KeyFrame startFadeIn = new KeyFrame(Duration.seconds(durationInSeconds * 3 * i), 
            new KeyValue(slide.opacityProperty(), 0));

        KeyFrame endFadeIn = new KeyFrame(Duration.seconds(durationsInSeconds * (3 * i + 1)), 
            new KeyValue(slide.opacityProperty(), 1));

        KeyFrame startFadeOut = new KeyFrame(Duration.seconds(durationInSeconds * (3 * i + 2)), 
            new KeyValue(slide.opacityProperty(), 1));

        slideshow.getKeyFrames().addAll(newImageFrame, startFadeIn, endFadeIn, startFadeOut);

    }
    slideshow.play();
}