如何解析直接内存中的 Google Protocol Buffers 而无需在 Java 中分配堆字节数组?
How to parse Google Protocol Buffers that in the direct memory without allocating heap byte array in Java?
我正在尝试将不在 JVM 堆中的 ByteBuf 解析为 Google Protocol Buffer 对象。其实就是Netty传给我的直接内存字节缓冲区。
这是我目前正在做的事情:
ByteBuf buf = ...;
ByteBufInputStream stream = new ByteBufInputStream(buf);
Message msg = MyPbMessage.getDefaultInstance().getParserForType().parseFrom(stream);
这可行。但是,我发现这种类型的解析会为每条消息引入新的字节数组,并导致大量 GC。
那么有没有办法避免在堆字节数组中创建这些?即,直接从本机内存解析 Google Protocol Buffer 字节。
你可以做到 the way the Guava guys do 在 ThreadLocal 中存储一个小缓冲区(1024 字节),如果足够就使用它并且永远不要在 TL 中放置更大的缓冲区。
只要它可以满足大多数请求,它就可以正常工作。如果 average/median 尺寸太大,您可以参考 soft/weak,但是,如果没有一些实际测试,很难说它是否有帮助。
你可以结合使用这两种方法,即在 TL 中使用强引用的小缓冲区和弱引用的大缓冲区。你可以汇集你的缓冲区,你可以...
...但请注意,这一切都有其阴暗面。浪费的内存,延长的缓冲区生命周期导致将它们提升到垃圾收集成本更高的老年代。
我正在尝试将不在 JVM 堆中的 ByteBuf 解析为 Google Protocol Buffer 对象。其实就是Netty传给我的直接内存字节缓冲区。
这是我目前正在做的事情:
ByteBuf buf = ...;
ByteBufInputStream stream = new ByteBufInputStream(buf);
Message msg = MyPbMessage.getDefaultInstance().getParserForType().parseFrom(stream);
这可行。但是,我发现这种类型的解析会为每条消息引入新的字节数组,并导致大量 GC。
那么有没有办法避免在堆字节数组中创建这些?即,直接从本机内存解析 Google Protocol Buffer 字节。
你可以做到 the way the Guava guys do 在 ThreadLocal 中存储一个小缓冲区(1024 字节),如果足够就使用它并且永远不要在 TL 中放置更大的缓冲区。
只要它可以满足大多数请求,它就可以正常工作。如果 average/median 尺寸太大,您可以参考 soft/weak,但是,如果没有一些实际测试,很难说它是否有帮助。
你可以结合使用这两种方法,即在 TL 中使用强引用的小缓冲区和弱引用的大缓冲区。你可以汇集你的缓冲区,你可以...
...但请注意,这一切都有其阴暗面。浪费的内存,延长的缓冲区生命周期导致将它们提升到垃圾收集成本更高的老年代。