首页 > 解决方案 > 迭代大小为 350 万的编年史地图的更好方法是什么

问题描述

我已将编年史地图实现为:

ChronicleMapBuilder
                .of(LongValue.class, ExceptionQueueVOInterface.class)
                .name(MAP_NAME)
                .entries(2_000_000)
                .maxBloatFactor(3)
                .create();

Map 有大约 350 万条记录。我正在使用此映射到服务器作为搜索操作的缓存。很多时候要搜索条目列表,我们必须遍历整个地图。350 万条记录占用 8.7 GB 的 RAM,我的 java 堆分配内存为 36 GB。服务器中的总 RAM 为 49 GB。当我使用以下代码迭代地图时:

map.forEachEntry(entry -> {
        if(exportSize.get() != MAX_EXPORT_SIZE && TeamQueueFilter.applyFilter(exceptionFilters, entry.value().get(), queType, uid)){
            ExceptionQueue exceptionQueue = getExceptionQueue(entry.value().get());
            if(exceptionFilters.isRts23Selected() || exceptionQueue.getMessageType().equals(MessageType.RTS23.toString())){
                exceptionQueue.setForsId(Constant.BLANK_STRING);
                rts23CaseIdMap.put(String.valueOf(entry.key().get().getValue()), exceptionQueue);
            }else {
                handleMessage(exceptionQueue, entry.key().get(), caseDetailsList);
            }
            exportSize.incrementAndGet();
        }
    });

它总是给我记忆错误。VM.array 大小小于可用内存。在这里迭代这个大地图的任何提示。感谢帮助。

标签: java-8chronicle-map

解决方案


我不得不猜测,因为您在这里没有提供任何错误,所以您收到的错误消息类似于java.lang.OutOfMemoryError: Direct buffer memory.

Chronicle Map 不会在堆上分配其内容,而是使用堆外内存映射,并且可能您的堆外空间已用完。您需要检查磁盘上 Chronicle Map 文件的大小,相同数量的堆外内存将用于映射。

可以使用 -XX:MaxDirectMemorySize 标志调整堆外内存。


推荐阅读