简体   繁体   English

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

[英]Java3D: How to avoid OutOfMemoryError while using textures

I'm creating several visual objects in loop: 我在循环中创建了几个可视对象:

...
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
}
...

The Package is basically just a simple cube with a texture. Package基本上只是一个带纹理的简单立方体。 The constructer of package looks as follows: 包的构造如下:

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

So I'm loading the same texture over and over again in the loop which eventually causes an OutOfMemoryError. 所以我在循环中一遍又一遍地加载相同的纹理,最终导致OutOfMemoryError。 Is there anyway to avoid/optimise that? 反正有没有避免/优化?

The most obvious optimization is to cache your BufferedImage : 最明显的优化是缓存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);
   }
}

Depending on the manipulations you make later, you could also cache your ImageComponent2D objects and/or your Texture2D objects. 根据您稍后进行的操作,您还可以缓存ImageComponent2D对象和/或Texture2D对象。

Instead of creating a new Texture over and over again, try rearranging your code so it reuses the same texture. 不要反复创建新的纹理,而是尝试重新排列代码,使其重用相同的纹理。 This way, the texture only needs to be loaded once, and uses less memory because of that. 这样,纹理只需要加载一次,因此使用更少的内存。

So the short answer is yes. 所以简短的回答是肯定的。 you can optimize, it looks like unless i am mistaken that in theory you could reuse that same "Package" object, and just change some params within it to reduce memory use, you are loading that texture in multiple times into memory for the packages you create 你可以优化,看起来除非我错了理论上你可以重用相同的“Package”对象,只是更改其中的一些参数以减少内存使用,你将多次将该纹理加载到内存中用于包你创造

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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