在本机内存中存储多个字节数组

Posted

技术标签:

【中文标题】在本机内存中存储多个字节数组【英文标题】:Store multiple byte-arrays in native memory 【发布时间】:2021-06-15 18:36:26 【问题描述】:

我有固定数量的固定长度的字节数组 (byte[]) 我想存储在本机内存中(并稍后检索)。但是,我不太确定如何将多个数组直接存储在 MemorySegment 中。

我知道我可能会创建一个大型 MemorySegment 并逐个元素地对其进行初始化,但我认为这种策略会很慢并且会使检索更加麻烦(也许?)。

在 API 文档中,我遇到了 SegmentAllocator 抽象,这似乎解决了我的分配问题,但我不明白如何使用此 SegmentAllocator 检索分配的数据。

try(ResourceScope scope = ResourceScope.newConfinedScope())
    byte[] data = objToByteArray(someClass.getDeclaredConstructor().newInstance());  //suppose data is always of constant length                    
    SegmentAllocator alloc = SegmentAllocator.arenaAllocator(numOfArrays* data.length, scope);
    for(int i = 0; i < numOfArrays; i++)
        alloc.allocateArray(MemoryLayouts.JAVA_BYTE, data);
        data = objToByteArray(someClass.getDeclaredConstructor().newInstance());
    
    //how can I access the arrays in alloc?
catch(Exception e)
    e.printStackTrace();

有没有办法访问 SegmentAllocator 中的数据,或者是否有其他方法可以解决我的问题?

【问题讨论】:

你似乎忽略了allocateArray的返回值,它返回了包含数据的MemorySegment 【参考方案1】:

看来您在这里要做的是将这些字节数组端到端复制到某个内存段中。

您应该首先分配一个大内存段,在循环中将其切片,然后一次将一个字节数组复制到一个切片中:

try (ResourceScope scope = ResourceScope.newConfinedScope()) 
    byte[] data = objToByteArray(someClass.getDeclaredConstructor().newInstance());  //suppose data is always of constant length
    long stride = data.length;
    // allocate segment
    MemorySegment segment = MemorySegment.allocateNative(numOfArrays * stride, scope);
    
    // copy arrays to segment
    for (int i = 0; i < numOfArrays; i++) 
        MemorySegment slice = segment.asSlice(i * stride, stride);
        slice.copyFrom(MemorySegment.ofArray(data));
        data = objToByteArray(someClass.getDeclaredConstructor().newInstance());
    

    // read arrays back
    for (int i = 0; i < numOfArrays; i++) 
        MemorySegment slice = segment.asSlice(i * stride, stride);
        data = slice.toByteArray();
        System.out.println(Arrays.toString(data));
    
 catch (Exception e) 
    e.printStackTrace();

(另外,FWIW,您最终会在填充循环的最后一次迭代中创建一个从未实际使用过的额外字节数组)。

【讨论】:

感谢您的回答。我实际上最终找到了一种非常相似的方法。但是我不确定这种策略是否比手动将字节数组复制到段中(逐个元素)更快(因为我有多个线程不断地将数据写入段(同时))。我相信不断创建 MemorySegments (-->asSlice) 会对性能(垃圾收集开销)产生负面影响。

以上是关于在本机内存中存储多个字节数组的主要内容,如果未能解决你的问题,请参考以下文章

PHP数组到底占用多少内存空间

C语言中如何计算一个数组占内存多少空间?

c关于数组所占内存大小问题

JAVA里String数组在内存分配中分配的空间每个占几个字节?

使用 concat() 时 JPA 本机查询返回字节数组而不是字符串

大字节数组 - 在字节数组中存储长度有啥好处?