【问题标题】:Chronicle Queue Read/write from queue using zero allocationChronicle Queue 使用零分配从队列读取/写入
【发布时间】:2021-01-24 18:10:46
【问题描述】:

我是编年史队列的新用户,我想使用零分配策略来读取和写入编年史队列中的对象。我想使用队列和像 pojo 类这样的字节的可编组实现是正确的策略吗? 我没有找到任何可以帮助我的东西。 我尝试在下面做一个消息类的实例来追加和读取队列中的内容。当我尝试使用多个线程阅读时,我总是会出现内存不足错误。

public class Message implements BytesMarshallable{
    private byte[] text;
    private long timeStamp;
    
    public Message(){}

    //Getters and Setters
}

当我遇到多个线程的内存不足错误时,我尝试使用 tailer.readDocument 读取

【问题讨论】:

    标签: java queue byte chronicle chronicle-queue


    【解决方案1】:

    使用byte[] 需要您在每次大小更改时分配一个新的。您无法更改 byte[] 的大小。

    相反,我建议使用 out Bytes 类,该类可以调整大小而不会产生太多垃圾(仅在增长时才有时)

    package run.chronicle.queue;
    
    import net.openhft.chronicle.bytes.Bytes;
    import net.openhft.chronicle.wire.BytesInBinaryMarshallable;
    import net.openhft.chronicle.wire.LongConversion;
    import net.openhft.chronicle.wire.MilliTimestampLongConverter;
    
    public class Message extends BytesInBinaryMarshallable {
        private final Bytes text = Bytes.allocateElasticOnHeap();
    
        @LongConversion(MilliTimestampLongConverter.class)
        private long timeStamp;
    
        //Getters and Setters
    
    
        public Bytes getText() {
            return text;
        }
    
        public void setText(CharSequence text) {
            this.text.clear().append(text);
        }
    
        public long getTimeStamp() {
            return timeStamp;
        }
    
        public void setTimeStamp(long timeStamp) {
            this.timeStamp = timeStamp;
        }
    }
    

    见这个例子https://github.com/OpenHFT/Chronicle-Queue-Demo/tree/master/messages-with-text

    当使用小堆 -Xmx128m -XX:NewSize=96m -verbose:gc MessageMain 运行时,您可以看到数百万条消息不会触发任何收集。

    Read 10,000,000 of 10,000,000 messages in 7.990 seconds
    Read 10,000,000 of 10,000,000 messages in 6.907 seconds
    [main] INFO net.openhft.chronicle.bytes.MappedFile - Took 2 ms to add mapping for test-438402668456/metadata.cq4t
    Read 10,000,000 of 10,000,000 messages in 6.836 seconds
    [main] INFO net.openhft.chronicle.bytes.MappedFile - Took 2 ms to add mapping for test-445239126125/metadata.cq4t
    Read 10,000,000 of 10,000,000 messages in 6.883 seconds
    [main] INFO net.openhft.chronicle.bytes.MappedFile - Took 3 ms to add mapping for test-452122895277/metadata.cq4t
    Read 10,000,000 of 10,000,000 messages in 7.013 seconds
    Read 10,000,000 of 10,000,000 messages in 6.838 seconds
    [main] INFO net.openhft.chronicle.bytes.MappedFile - Took 2 ms to add mapping for test-465974753213/metadata.cq4t
    

    【讨论】:

    • 嗨,彼得,感谢您的帮助。在这个例子中使用字节获得了最好的性能,我的意思是我想避免你提到的 GC 运行,我有最大的缓冲区大小。例如,我可以使用 BytesInBinaryMarshallable 和二进制队列在编年史队列中获得最佳的读写性能?
    • @DomenicoSchettiniFilho Bytes 将根据需要调整大小,但您可以提供特定大小来调整它。我不确定你的问题是什么,你能改写一下吗?
    • 当然是彼得。如果可能或保持在最低限度,我正试图获得最佳性能,以从零 gc 的编年史队列中写入和读取。正如我所描述的,我的课程有一些文本字段和诸如时间戳之类的原语。由于我有最大缓冲区大小,我可以调整 gc 可能不调整字节大小。除此之外,您认为此解决方案的队列读取/写入性能是否不错?
    • @DomenicoSchettiniFilho 你可以看到开销,在这种情况下,大约为 0·3 微秒,有一些更快的选项,但它们更难使用,所以我会从这个开始。
    • 好彼得。如果您有更快的选择的参考,我也会尝试。无论如何,即使更难,我也会对更多选项进行基准测试。感谢您的帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多