即使已将代表图像的变量分配给新图像,如何停止将图像保存在ram中

时间:2019-07-16 00:48:03

标签: java raspberry-pi processing

我是高中三年级程序员,所以不是一个完整的初学者,但是我无法修复此错误;当我在Processing 3.5.3中将图像加载到变量中,然后将其复制到另一个变量时,因为我将第一个变量设置为新图像,然后在加载后将其转移到第二个图像上,并重复不确定的次数。无论我做什么来清除变量,草图最终都会耗尽内存

我尝试在每次代码迭代时将所有内容都设置为null并运行垃圾收集器,但最终最终总会耗尽内存。

这是我的代码:

import java.io.FileWriter;
import java.io.FileReader;

int m=0, last=0, nums;
PImage show, img;
private FileWriter csvWriter;

int count=1;
void setup()
{
  //fullScreen();
  size(1800, 900);
  imageMode(CENTER);
  noStroke();

  nums == /*the number of images to be cycled through*/
  frameRate(.1);
}

void draw()
{
  testDraw();
  Runtime.getRuntime().gc();
  g.removeCache(img);
  g.removeCache(show);

  System.gc();
}

public void testDraw()
{
  int num = (int)(Math.random()*nums);
  println("image number: "+ num);
  int count=0;
  String data=null;

  try
  {
    BufferedReader csvReader = new BufferedReader(new FileReader(/*a csv with the paths of the images to be loaded*/));  
    while (count<num) 
    {  
      csvReader.readLine();
      count++;
    }
    data=csvReader.readLine();



    csvReader.close();
    csvReader=null;
  }
  catch (IOException e) 
  {
    e.printStackTrace();
  }


  if (frameCount ==1)
  {
    try
    {
      img = loadImage(data);
    } 
    catch (Exception e)
    {
      e.printStackTrace();
    }
    while (data != null && img.width<=0)
    {
      //println("loading...");
    }
  }
  show = img.copy();
  img=null;
  displayImage(show);
  show=null;



  try
  {
    println("available ram: " + Runtime.getRuntime().freeMemory());
    img = loadImage(data);
  } 
  catch (Exception e)
  {
    e.printStackTrace();
  }
  while (data != null && img.width<=0)
  {
    //println("loading...");
  }

  data=null;
}

public void displayImage(PImage in)
{

  if ((((float)(width)/in.width)*in.height)<height)
  {
    image(in, width/2, height/2, width, ((float)(width)/in.width)*in.height);
  } else
  {
    image(in, width/2, height/2, ((float)(height)/in.height)*in.width, height);
  }
}

该代码应该从网络驱动器加载并在屏幕上显示图像,网络部分可以正常工作并显示图像,但是应该每隔几秒钟就永久加载一个新图像,但是由于错误而崩溃讯息:

OutOfMemoryError: You may need to increase the memory setting in Preferences.

和打印输出:

java.lang.OutOfMemoryError: Java heap space
OutOfMemoryError: Java heap space
    at java.awt.image.DataBufferInt.<init>(DataBufferInt.java:75)
    at java.awt.image.Raster.createPackedRaster(Raster.java:467)
    at java.awt.image.DirectColorModel.createCompatibleWritableRaster(DirectColorModel.java:1032)
    at sun.awt.image.ImageRepresentation.createBufferedImage(ImageRepresentation.java:253)
    at sun.awt.image.ImageRepresentation.setPixels(ImageRepresentation.java:559)
    at sun.awt.image.ImageDecoder.setPixels(ImageDecoder.java:138)
    at sun.awt.image.JPEGImageDecoder.sendPixels(JPEGImageDecoder.java:119)
    at sun.awt.image.JPEGImageDecoder.readImage(Native Method)
    at sun.awt.image.JPEGImageDecoder.produceImage(JPEGImageDecoder.java:141)
    at sun.awt.image.InputStreamImageSource.doFetch(InputStreamImageSource.java:269)
    at sun.awt.image.ImageFetcher.fetchloop(ImageFetcher.java:205)
    at sun.awt.image.ImageFetcher.run(ImageFetcher.java:169)
An OutOfMemoryError means that your code is either using up too much memory
because of a bug (e.g. creating an array that's too large, or unintentionally
loading thousands of images), or that your sketch may need more memory to run.
If your sketch uses a lot of memory (for instance if it loads a lot of data files)
you can increase the memory available to your sketch using the Preferences window.

我尝试增加内存,但这只会延迟最终的内存不足崩溃

请帮助,我会尽力回答有关我的代码的任何问题

1 个答案:

答案 0 :(得分:0)

作为程序员,您永远不能直接强制垃圾收集器运行。致电Runtime.getRuntime().gc()只是一个建议。 JVM可以(可能会)忽略它。 Javadoc对此有一些修饰语:https://docs.oracle.com/javase/7/docs/api/java/lang/Runtime.html#gc()

取决于您增加了多少JVM内存,以及让它运行了多长时间,尝试更大的内存量可能仍然有价值。例如,您可以尝试使用-Xmx=4096m以最大4GB的堆大小运行。

最后,我将更仔细地研究当您调用img.copy()image()时发生的情况。一种或两种方式都有可能导致保留对基础图像的引用,从而使img=nullshow=null不能达到您想要的效果(允许对基础图像数据进行垃圾回收)