Skip to content

Commit 9e7c2a9

Browse files
committed
potentially fix memory leak
1 parent 7de1fd9 commit 9e7c2a9

File tree

3 files changed

+75
-2
lines changed

3 files changed

+75
-2
lines changed

src/main/java/bwapi/UnsafeTools.java

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package bwapi;
2+
3+
import sun.misc.Unsafe;
4+
5+
import java.lang.reflect.Field;
6+
import java.nio.Buffer;
7+
8+
class UnsafeTools {
9+
10+
private static Object getOrCrash(final Class<?> className, final Object object, final String fieldName) {
11+
try { // get
12+
final Field field = className.getDeclaredField(fieldName);
13+
final boolean accessible = field.isAccessible();
14+
if (!accessible) {
15+
field.setAccessible(true);
16+
}
17+
final Object result = field.get(object);
18+
if (!accessible) {
19+
field.setAccessible(false);
20+
}
21+
return result;
22+
23+
} catch (final Exception e) { // or crash...
24+
e.printStackTrace();
25+
System.exit(-1);
26+
return null;
27+
}
28+
}
29+
30+
static Unsafe getUnsafe() {
31+
return (Unsafe) getOrCrash(Unsafe.class, null, "theUnsafe");
32+
}
33+
34+
/**
35+
* Alternative to `((DirectBuffer) buffer).address())`
36+
* (ab)using reflection
37+
*/
38+
static long getAddress(final Buffer buffer) {
39+
return (long) getOrCrash(Buffer.class, buffer, "address");
40+
}
41+
}

src/main/java/bwapi/WrappedBuffer.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package bwapi;
22

3-
import com.sun.jna.Memory;
43
import com.sun.jna.Pointer;
54
import sun.misc.Unsafe;
65

@@ -29,7 +28,8 @@ class WrappedBuffer {
2928
}
3029

3130
WrappedBuffer(final int size) {
32-
this(new Memory(size), size);
31+
buffer = ByteBuffer.allocateDirect(size);
32+
address = UnsafeTools.getAddress(buffer);
3333
}
3434

3535
WrappedBuffer(final Pointer pointer, final int size) {
@@ -90,6 +90,7 @@ void putString(final int offset, final int maxLen, final String string) {
9090
unsafe.putByte(pos, (byte) 0);
9191
}
9292

93+
9394
ByteBuffer getBuffer() {
9495
return buffer;
9596
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package bwapi;
2+
3+
import org.junit.Test;
4+
import sun.misc.Unsafe;
5+
6+
import java.nio.ByteBuffer;
7+
8+
import static org.junit.Assert.*;
9+
10+
public class UnsafeToolsTest {
11+
12+
@Test
13+
public void testGettingUnsafe() {
14+
assertNotNull(UnsafeTools.getUnsafe());
15+
}
16+
17+
@Test
18+
public void testDirectByteBuffer() {
19+
byte[] bytes = {112, 117, 114, 112, 108, 101, 119, 97, 118, 101};
20+
final ByteBuffer buffer = ByteBuffer.allocateDirect(bytes.length);
21+
buffer.put(bytes);
22+
23+
long address = UnsafeTools.getAddress(buffer);
24+
assertNotEquals(0, address);
25+
26+
Unsafe unsafe = UnsafeTools.getUnsafe(); //to obtain memory values via the address
27+
for (int i=0; i < bytes.length; i++) {
28+
assertEquals(bytes[i], unsafe.getByte(address + i));
29+
}
30+
}
31+
}

0 commit comments

Comments
 (0)