PooledUnsafeDirectByteBuf не найден в DirectMemory

Я использую Netty 4.1.17-Final.

Я написал код для отправки и получения 100 МБ случайных ASCII. Декодер не читает, пока ByteBuf не станет 100 МБ.

@Override
public void decode(ByteBuffer _in, List<Object> _out) {
    if (_in.remaining() == size) {   // size = 100 * 1024 * 1024
        _in.get(new byte[size]);
    }
}

Поэтому Netty буферизует 100 МБ, но это не было найдено даже при мониторинге Direct Memory.

System.out.println(sun.misc.SharedSecrets.getJavaNioAccess().getDirectBufferPool().getMemoryUsed());
ManagementFactory.getPlatformMXBeans(BufferPoolMXBean.class).forEach(buf -> {
    System.out.printf("%s: Used=%d, TotalCap=%d%n", buf.getName(), buf.getMemoryUsed(), buf.getTotalCapacity());
});

// Result
// 10
// direct: Used=9, TotalCap=8
// mapped: Used=0, TotalCap=0

Нетти использовал PooledUnsafeDirectByteBuf, но где вы буферизуете полученные данные? Или метод прямого мониторинга буфера неверен?

2 ответа

Решение

Вы можете сказать нетти не использовать Unsafe для прямых буферов, и поэтому он снова появится в JMX. К сожалению, это также будет иметь некоторое влияние на производительность.

Просто используйте -Dio.netty.maxDirectMemory=0,

См.: https://github.com/netty/netty/blob/4.1/common/src/main/java/io/netty/util/internal/PlatformDependent.java#L153

Самостоятельный ответ. В моем коде Netty приобрела DirectMemory с помощью com.sun.Unsafe. Эта область не может быть захвачена с помощью BufferPoolMXBean или SharedSecrets.

Я пытался получить память с помощью Unsafe, но это не было выведено на результат мониторинга.

Field unsafeField = Unsafe.class.getDeclaredField("theUnsafe");
unsafeField.setAccessible(true);
Unsafe unsafe = (Unsafe) unsafeField.get(null);
unsafe.allocateMemory(1000);

Я нашел следующий запрос.
расширение для отслеживания использования памяти вне кучи для netty · Проблема № 475 · Netflix/ зритель

Скажите, пожалуйста, есть ли способ получить размер, полученный Unsafe.

Другие вопросы по тегам