Я пытаюсь найти собственную утечку памяти в моем производственном приложении. Проблема в том, чтобы узнать, какой метод в моем коде делает unsafe.allocateMemory(size)
без unsafe.freeMemory(startIndex)
Это для Ubuntu 18.04, Java-версия "1.8.0_191".
// Example of "Unlimited array"
class DirectIntArray implements Closeable {
private final static long INT_SIZE_IN_BYTES = 4;
private final long startIndex;
private final Unsafe unsafe;
public DirectIntArray(long size) throws NoSuchFieldException, IllegalAccessException {
unsafe = getUnsafe();
startIndex = unsafe.allocateMemory(size * INT_SIZE_IN_BYTES);
unsafe.setMemory(startIndex, size * INT_SIZE_IN_BYTES, (byte) 0);
}
@Override
public void close() throws IOException {
unsafe.freeMemory(startIndex);
}
public void setValue(long index, int value) {
unsafe.putInt(index(index), value);
}
public int getValue(long index) {
return unsafe.getInt(index(index));
}
private long index(long offset) {
return startIndex + offset * INT_SIZE_IN_BYTES;
}
private static Unsafe getUnsafe() throws IllegalAccessException, NoSuchFieldException {
Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
theUnsafe.setAccessible(true);
return (Unsafe) theUnsafe.get(null);
}
}
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, InterruptedException {
int cnt = 0;
System.out.println("Use big array in off-heap without freeing memory");
while (true) {
useWithLeak(MB);
Thread.sleep(10);
System.out.println(++cnt + "MB Allocated");
}
}
public static void useWithLeak(long len) {
try {
DirectIntArray arr = new DirectIntArray(len);
arr.setValue(1, 111);
arr.setValue(len, 222);
System.out.println("Read from off-heap values: " + arr.getValue(1) + ", " + arr.getValue(len));
} catch (IllegalAccessException | NoSuchFieldException e) {
e.printStackTrace();
}
}
Итак, я написал код, который производит утечку памяти, и я хочу найти метод, который это делает. Я использую jemalloc
, и у меня есть файл .gif, который я получил в соответствии с этой инструкцией . У меня есть изображение
Так как я мог догадаться, что 0x00007f2e42297ea7
- это useWithLeak
метод? Это реально?