内存问题:在Map中存储大量数据

时间:2015-08-07 13:43:58

标签: java list dictionary

我有以下情况:

  1. 来自外部系统的大量消息列表(消息包含id和有效负载)
  2. 我根据id过滤这些消息,并将有效负载存储在列表中,最后将id和List存储在地图中。
  3. 后来基于id,我正从map中检索有效载荷列表,并提交整个有效载荷列表,以便进一步处理到执行服务。
  4. 好吧,我不喜欢这种方法,因为在运行时我有一个包含所有数据的地图(第2点)。我可能最终会遇到与内存相关的问题。是否有上述方法的替代方案。

    修改

    我正在使用Java。我从一些外部系统获取消息(我不知道可能出现的消息量),最后根据它们的ID处理它们。处理完毕后,它们将存储在数据库中。但是,问题是我根据ID将消息加载到Map中。我必须根据ID对消息进行分组,然后发送进行处理。因此,我必须将整个地图保留在内存中一段时间​​。

    提前致谢。

1 个答案:

答案 0 :(得分:2)

我记得我自己使用MapDB。 基本上它为您提供了一个Map接口,但由off-heap memory备份(想想Linux中的内存映射文件)。

您可以在此处找到示例:https://github.com/jankotek/mapdb/blob/master/src/test/java/examples/CacheOffHeap.java

将此处复制相关部分以便于参考:

        final double cacheSizeInGB = 1.0;

        // Create cache backed by off-heap store
        // In this case store will use ByteBuffers backed by byte[].
        HTreeMap cache = DBMaker
                .memoryDirectDB()
                .transactionDisable()
                .make()
                .hashMapCreate("test")
                .expireStoreSize(cacheSizeInGB) //TODO not sure this actually works
                .make();

        //generates random key and values
        Random r = new Random();
        //used to print store statistics
        Store store = Store.forEngine(cache.getEngine());


        // insert some stuff in cycle
        for(long counter=1; counter<1e8; counter++){
            long key = r.nextLong();
            byte[] value = new byte[1000];
            r.nextBytes(value);

            cache.put(key,value);

            if(counter%1e5==0){
                System.out.printf("Map size: %,d, counter %,d, store size: %,d, store free size: %,d\n",
                        cache.sizeLong(), counter, store.getCurrSize(),  store.getFreeSize());
            }

        }

        // and release memory. Only necessary with `DBMaker.memoryDirect()`
        cache.close();