Java3D:如何在使用纹理时避免OutOfMemoryError

时间:2012-04-03 10:30:35

标签: java textures out-of-memory java-3d

我在循环中创建了几个可视对象:

...
Package packet; // a visual packet
for(int i = 0; i < numberOfSteps; i++){
  packet = new Package(packetSize, packetSize, packetSize);

  // position, rotate, etc. and add to scene graph
}
...

Package基本上只是一个带纹理的简单立方体。包的构造如下:

public Package(float x, float y, float z) {
    Appearance appear = new Appearance();
    BufferedImage filename = null;

    try {
        filename = ImageIO.read(getClass().getResource("package.jpg"));
    } catch (IOException e) {
                    e.printStackTrace();
        System.exit(1);
    }

    TextureLoader loader = new TextureLoader(filename);
    ImageComponent2D image = loader.getImage();
    Texture2D texture = new Texture2D(Texture.BASE_LEVEL, Texture.RGBA,
            image.getWidth(), image.getHeight());
    texture.setImage(0, image);
    appear.setTexture(texture);
    textureCube = new Box(x, y, z, Box.GENERATE_TEXTURE_COORDS, appear);
}

所以我在循环中一遍又一遍地加载相同的纹理,最终导致OutOfMemoryError。无论如何都要避免/优化它?

3 个答案:

答案 0 :(得分:3)

最明显的优化是缓存您的BufferedImage

class ImageProvider{

   private static Map<String, Image> images = new HashMap<String, Image>();

   public static Image getImage(String filename){
       if(!images.contains(filename))
           try {
              images.put(filename, ImageIO.read(ImageProvider.class.getResource(filename));
           } catch (IOException ignore){
              //will return null if image cannot be loaded
           }

       return images.get(filename);
   }
}

根据您稍后进行的操作,您还可以缓存ImageComponent2D个对象和/或Texture2D个对象。

答案 1 :(得分:0)

不要一遍又一遍地创建新纹理,而是尝试重新排列代码,使其重用相同的纹理。这样,纹理只需要加载一次,并因此使用更少的内存。

答案 2 :(得分:0)

所以简短的回答是肯定的。你可以优化,看起来除非我错了理论上你可以重用相同的“Package”对象,只是更改其中的一些参数以减少内存使用,你将多次将该纹理加载到内存中用于包你创建