简体   繁体   中英

how to stop images from being saved in ram even when the variable they are represented by has been assigned to a new image

I am a third year programmer in high school, so not a complete beginner, but I cannot fix this bug; When I load an image into a variable in Processing 3.5.3 and then copy it to another variable, as I set the first variable to a new image and then transfer it over to the second once it loads, and repeat an undetermined number of times. no matter what I do to clear the variables, the sketch eventually runs out of memory

I have tried setting everything to null with each iteration of the code and running the garbage collector but it always runs out of memory eventually.

Here is my code:

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);
  }
}

the code is supposed to load and display and image on a screen from a network drive, the network part works and it displays images but it is supposed to load a new image every few seconds, forever, but it crashes with the error message:

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

and the printout:

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.

I have tried increasing the memory but it just delays the eventual out of memory crash

please help, and I will do my best to answer any questions about my code

As a programmer, you can never directly force the garbage collector to run. Calling Runtime.getRuntime().gc() is just a suggestion. The JVM can (and probably will) ignore it. There's some verbiage about that in Javadoc here: https://docs.oracle.com/javase/7/docs/api/java/lang/Runtime.html#gc()

Depending on how much you've increased JVM memory, and for how long you've let it run, there may still be value in trying larger memory amounts. As an example, you could try running with max heap size of 4GB by using -Xmx=4096m .

Lastly, I would look more closely at what happens when you call img.copy() and image() . It's possible that one or both somehow results in retaining a reference to the underlying image that such that img=null or show=null doesn't have the effect you want (of allowing the underlying image data to be garbage collected).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM