BufferUtils : ensureLargeEnough now set the limit to the buffer capacity if it exists to avoid creating a new buffer instead of reusing the previous one.

see http://jmonkeyengine.org/groups/development-discussion-jme3/forum/topic/bugbufferleak-in-ensurelargeenoughbitmaptextpage/?#post-188976

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@9730 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
3.0
rem..om 12 years ago
parent d2e6648eb3
commit 2577485727
  1. 47
      engine/src/core/com/jme3/util/BufferUtils.java

@ -77,7 +77,7 @@ public final class BufferUtils {
public static void setTrackDirectMemoryEnabled(boolean enabled) { public static void setTrackDirectMemoryEnabled(boolean enabled) {
trackDirectMemory = enabled; trackDirectMemory = enabled;
} }
/** /**
* Creates a clone of the given buffer. The clone's capacity is * Creates a clone of the given buffer. The clone's capacity is
* equal to the given buffer's limit. * equal to the given buffer's limit.
@ -305,7 +305,7 @@ public final class BufferUtils {
* @param index * @param index
* the postion to place the data; in terms of quaternions not floats * the postion to place the data; in terms of quaternions not floats
*/ */
public static void setInBuffer(Quaternion quat, FloatBuffer buf, public static void setInBuffer(Quaternion quat, FloatBuffer buf,
int index) { int index) {
buf.position(index * 4); buf.position(index * 4);
buf.put(quat.getX()); buf.put(quat.getX());
@ -313,7 +313,7 @@ public final class BufferUtils {
buf.put(quat.getZ()); buf.put(quat.getZ());
buf.put(quat.getW()); buf.put(quat.getW());
} }
/** /**
* Sets the data contained in the given vector4 into the FloatBuffer at the * Sets the data contained in the given vector4 into the FloatBuffer at the
* specified index. * specified index.
@ -359,7 +359,7 @@ public final class BufferUtils {
buf.put((index * 3) + 2, vector.z); buf.put((index * 3) + 2, vector.z);
} }
} }
/** /**
* Updates the values of the given vector from the specified buffer at the * Updates the values of the given vector from the specified buffer at the
* index provided. * index provided.
@ -377,8 +377,8 @@ public final class BufferUtils {
vector.y = buf.get(index * 3 + 1); vector.y = buf.get(index * 3 + 1);
vector.z = buf.get(index * 3 + 2); vector.z = buf.get(index * 3 + 2);
} }
/** /**
* Generates a Vector3f array from the given FloatBuffer. * Generates a Vector3f array from the given FloatBuffer.
* *
* @param buff * @param buff
@ -1105,6 +1105,9 @@ public final class BufferUtils {
* the input buffer, not null * the input buffer, not null
*/ */
public static FloatBuffer ensureLargeEnough(FloatBuffer buffer, int required) { public static FloatBuffer ensureLargeEnough(FloatBuffer buffer, int required) {
if (buffer != null) {
buffer.limit(buffer.capacity());
}
if (buffer == null || (buffer.remaining() < required)) { if (buffer == null || (buffer.remaining() < required)) {
int position = (buffer != null ? buffer.position() : 0); int position = (buffer != null ? buffer.position() : 0);
FloatBuffer newVerts = createFloatBuffer(position + required); FloatBuffer newVerts = createFloatBuffer(position + required);
@ -1119,6 +1122,9 @@ public final class BufferUtils {
} }
public static ShortBuffer ensureLargeEnough(ShortBuffer buffer, int required) { public static ShortBuffer ensureLargeEnough(ShortBuffer buffer, int required) {
if (buffer != null) {
buffer.limit(buffer.capacity());
}
if (buffer == null || (buffer.remaining() < required)) { if (buffer == null || (buffer.remaining() < required)) {
int position = (buffer != null ? buffer.position() : 0); int position = (buffer != null ? buffer.position() : 0);
ShortBuffer newVerts = createShortBuffer(position + required); ShortBuffer newVerts = createShortBuffer(position + required);
@ -1133,6 +1139,9 @@ public final class BufferUtils {
} }
public static ByteBuffer ensureLargeEnough(ByteBuffer buffer, int required) { public static ByteBuffer ensureLargeEnough(ByteBuffer buffer, int required) {
if (buffer != null) {
buffer.limit(buffer.capacity());
}
if (buffer == null || (buffer.remaining() < required)) { if (buffer == null || (buffer.remaining() < required)) {
int position = (buffer != null ? buffer.position() : 0); int position = (buffer != null ? buffer.position() : 0);
ByteBuffer newVerts = createByteBuffer(position + required); ByteBuffer newVerts = createByteBuffer(position + required);
@ -1149,7 +1158,7 @@ public final class BufferUtils {
public static void printCurrentDirectMemory(StringBuilder store) { public static void printCurrentDirectMemory(StringBuilder store) {
long totalHeld = 0; long totalHeld = 0;
long heapMem = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory(); long heapMem = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
boolean printStout = store == null; boolean printStout = store == null;
if (store == null) { if (store == null) {
store = new StringBuilder(); store = new StringBuilder();
@ -1201,7 +1210,7 @@ public final class BufferUtils {
private static Method viewedBufferMethod = null; private static Method viewedBufferMethod = null;
private static Method freeMethod = null; private static Method freeMethod = null;
private static Method loadMethod(String className, String methodName){ private static Method loadMethod(String className, String methodName) {
try { try {
Method method = Class.forName(className).getMethod(methodName); Method method = Class.forName(className).getMethod(methodName);
method.setAccessible(true); method.setAccessible(true);
@ -1224,19 +1233,19 @@ public final class BufferUtils {
// threads // threads
synchronized (BufferUtils.loadedMethods) { synchronized (BufferUtils.loadedMethods) {
// Oracle JRE / OpenJDK // Oracle JRE / OpenJDK
cleanerMethod = loadMethod("sun.nio.ch.DirectBuffer", "cleaner"); cleanerMethod = loadMethod("sun.nio.ch.DirectBuffer", "cleaner");
cleanMethod = loadMethod("sun.misc.Cleaner", "clean"); cleanMethod = loadMethod("sun.misc.Cleaner", "clean");
viewedBufferMethod = loadMethod("sun.nio.ch.DirectBuffer", "viewedBuffer"); viewedBufferMethod = loadMethod("sun.nio.ch.DirectBuffer", "viewedBuffer");
if (viewedBufferMethod == null){ if (viewedBufferMethod == null) {
// They changed the name in Java 7 (???) // They changed the name in Java 7 (???)
viewedBufferMethod = loadMethod("sun.nio.ch.DirectBuffer", "attachment"); viewedBufferMethod = loadMethod("sun.nio.ch.DirectBuffer", "attachment");
} }
// Apache Harmony // Apache Harmony
ByteBuffer bb = BufferUtils.createByteBuffer(1); ByteBuffer bb = BufferUtils.createByteBuffer(1);
Class<?> clazz = bb.getClass(); Class<?> clazz = bb.getClass();
try { try {
freeMethod = clazz.getMethod("free"); freeMethod = clazz.getMethod("free");
} catch (NoSuchMethodException ex) { } catch (NoSuchMethodException ex) {
} catch (SecurityException ex) { } catch (SecurityException ex) {
} }
@ -1245,14 +1254,14 @@ public final class BufferUtils {
/** /**
* Direct buffers are garbage collected by using a phantom reference and a * Direct buffers are garbage collected by using a phantom reference and a
* reference queue. Every once a while, the JVM checks the reference queue and * reference queue. Every once a while, the JVM checks the reference queue and
* cleans the direct buffers. However, as this doesn't happen * cleans the direct buffers. However, as this doesn't happen
* immediately after discarding all references to a direct buffer, it's * immediately after discarding all references to a direct buffer, it's
* easy to OutOfMemoryError yourself using direct buffers. This function * easy to OutOfMemoryError yourself using direct buffers. This function
* explicitly calls the Cleaner method of a direct buffer. * explicitly calls the Cleaner method of a direct buffer.
* *
* @param toBeDestroyed * @param toBeDestroyed
* The direct buffer that will be "cleaned". Utilizes reflection. * The direct buffer that will be "cleaned". Utilizes reflection.
* *
*/ */
public static void destroyDirectBuffer(Buffer toBeDestroyed) { public static void destroyDirectBuffer(Buffer toBeDestroyed) {

Loading…
Cancel
Save