0

我正在使用 Netty 4.1.17-Final。

我编写了发送和接收 100 MB 随机 ASCII 的代码。解码器在 ByteBuf 变为 100 MB 之前不会读取。

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

因此,Netty 缓冲了 100 MB,但即使通过监控 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

Netty 使用了 PooledUnsafeDirectByteBuf,但是你在哪里缓冲接收到的数据呢?还是直接缓冲监控方法不对?

4

2 回答 2

2

你可以告诉 Netty 不要使用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

于 2018-06-20T08:22:50.867 回答
0

自我回答,在我的代码中,Netty 使用 com.sun.Unsafe 获得了 DirectMemory。使用 BufferPoolMXBean 或 SharedSecrets 无法捕获此区域。

我尝试用 Unsafe 获取内存,但没有输出到监控结果。

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

我找到了以下请求。
用于跟踪 netty 的堆外内存使用的扩展 · 问题 #475 · Netflix/spectator

请告诉我是否有办法获得 Unsafe 获得的大小。

于 2018-06-20T07:17:52.697 回答