Memory usage improvements:

- blender context now disposes all its stored data and properly closes the BlenderInputStream
- fixed an error that causes unnecessary huge memory allocation in BlenderInputStream

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@9795 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
3.0
Kae..pl 12 years ago
parent 0b1681c29f
commit d4ddc2beeb
  1. 38
      engine/src/blender/com/jme3/scene/plugins/blender/BlenderContext.java
  2. 29
      engine/src/blender/com/jme3/scene/plugins/blender/file/BlenderInputStream.java

@ -31,6 +31,15 @@
*/ */
package com.jme3.scene.plugins.blender; package com.jme3.scene.plugins.blender;
import java.util.ArrayList;
import java.util.EmptyStackException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Stack;
import java.util.logging.Logger;
import com.jme3.animation.Bone; import com.jme3.animation.Bone;
import com.jme3.animation.Skeleton; import com.jme3.animation.Skeleton;
import com.jme3.asset.AssetManager; import com.jme3.asset.AssetManager;
@ -47,16 +56,6 @@ import com.jme3.scene.plugins.blender.file.Structure;
import com.jme3.scene.plugins.blender.meshes.MeshContext; import com.jme3.scene.plugins.blender.meshes.MeshContext;
import com.jme3.scene.plugins.blender.modifiers.Modifier; import com.jme3.scene.plugins.blender.modifiers.Modifier;
import com.jme3.scene.plugins.ogre.AnimData; import com.jme3.scene.plugins.ogre.AnimData;
import java.io.IOException;
import java.util.ArrayList;
import java.util.EmptyStackException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Stack;
import java.util.logging.Level;
import java.util.logging.Logger;
/** /**
* The class that stores temporary data and manages it during loading the belnd * The class that stores temporary data and manages it during loading the belnd
@ -629,14 +628,23 @@ public class BlenderContext {
return blenderKey.getDefaultMaterial(); return blenderKey.getDefaultMaterial();
} }
/**
* Clears all sotred resources and closes the blender input stream.
*/
public void dispose() { public void dispose() {
try { LOGGER.fine("Disposing blender context resources.");
inputStream.close(); inputStream.forceClose();
} catch (IOException e) {
LOGGER.log(Level.SEVERE, e.getLocalizedMessage(), e);
}
loadedFeatures.clear(); loadedFeatures.clear();
loadedFeaturesByName.clear(); loadedFeaturesByName.clear();
parentStack.clear();
loadedIpos.clear();
modifiers.clear();
constraints.clear();
animData.clear();
skeletons.clear();
meshContexts.clear();
boneContexts.clear();
helpers.clear();
} }
/** /**

@ -31,8 +31,6 @@
*/ */
package com.jme3.scene.plugins.blender.file; package com.jme3.scene.plugins.blender.file;
import com.jme3.asset.AssetManager;
import com.jme3.scene.plugins.blender.exceptions.BlenderFileException;
import java.io.BufferedInputStream; import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.IOException; import java.io.IOException;
@ -40,6 +38,9 @@ import java.io.InputStream;
import java.util.logging.Logger; import java.util.logging.Logger;
import java.util.zip.GZIPInputStream; import java.util.zip.GZIPInputStream;
import com.jme3.asset.AssetManager;
import com.jme3.scene.plugins.blender.exceptions.BlenderFileException;
/** /**
* An input stream with random access to data. * An input stream with random access to data.
* @author Marcin Roguski * @author Marcin Roguski
@ -67,8 +68,6 @@ public class BlenderInputStream extends InputStream {
protected int size; protected int size;
/** The current position of the read cursor. */ /** The current position of the read cursor. */
protected int position; protected int position;
/** The input stream we read the data from. */
protected InputStream inputStream;
/** /**
* Constructor. The input stream is stored and used to read data. * Constructor. The input stream is stored and used to read data.
@ -81,7 +80,6 @@ public class BlenderInputStream extends InputStream {
*/ */
public BlenderInputStream(InputStream inputStream, AssetManager assetManager) throws BlenderFileException { public BlenderInputStream(InputStream inputStream, AssetManager assetManager) throws BlenderFileException {
this.assetManager = assetManager; this.assetManager = assetManager;
this.inputStream = inputStream;
//the size value will canche while reading the file; the available() method cannot be counted on //the size value will canche while reading the file; the available() method cannot be counted on
try { try {
size = inputStream.available(); size = inputStream.available();
@ -104,6 +102,12 @@ public class BlenderInputStream extends InputStream {
this.readStreamToCache(bufferedInputStream); this.readStreamToCache(bufferedInputStream);
} catch (IOException e) { } catch (IOException e) {
throw new BlenderFileException("Problems occured while caching the file!", e); throw new BlenderFileException("Problems occured while caching the file!", e);
} finally {
try {
inputStream.close();
} catch (IOException e) {
LOGGER.warning("Unable to close stream with blender file.");
}
} }
try { try {
@ -128,12 +132,12 @@ public class BlenderInputStream extends InputStream {
cachedBuffer = new byte[size]; cachedBuffer = new byte[size];
size = 0;//this will count the actual size size = 0;//this will count the actual size
while (data != -1) { while (data != -1) {
cachedBuffer[size++] = (byte) data; if (size >= cachedBuffer.length) {//widen the cached array
if (size >= cachedBuffer.length) {//widen the cached array
byte[] newBuffer = new byte[cachedBuffer.length + (cachedBuffer.length >> 1)]; byte[] newBuffer = new byte[cachedBuffer.length + (cachedBuffer.length >> 1)];
System.arraycopy(cachedBuffer, 0, newBuffer, 0, cachedBuffer.length); System.arraycopy(cachedBuffer, 0, newBuffer, 0, cachedBuffer.length);
cachedBuffer = newBuffer; cachedBuffer = newBuffer;
} }
cachedBuffer[size++] = (byte) data;
data = inputStream.read(); data = inputStream.read();
} }
} }
@ -375,9 +379,12 @@ public class BlenderInputStream extends InputStream {
} }
@Override @Override
public void close() throws IOException { public void close() throws IOException { }
inputStream.close();
// cachedBuffer = null; /**
// size = position = 0; * This method should be used to close the stream because some loaders may close the stream while reading resources from it.
*/
public void forceClose() {
cachedBuffer = null;
} }
} }

Loading…
Cancel
Save