Java:ChronicleMap第2部分,超级RAM映射

诸如无处不在的HashMap类的标准Java Map最终受到可用RAM的限制。 阅读本文并了解如何创建几乎无限大小甚至超过目标计算机的RAM大小的Java Map。

内置的Map实现,例如HashMapConcurrentHashMap ,只要它们相对较小,就可以正常工作。 在所有情况下,它们都受可用堆的限制,因此最终受可用RAM大小的限制。 ChronicleMap可以将其内容存储在文件中,从而规避了此限制,为TB级的映射打开了空间,如有关CronicleMap系列文章的第二篇文章所示。

在我之前的第一篇文章中了解有关CronicleMap基础知识的更多信息。

文件映射

通过在ChronicleMap构建器上调用createPersistedTo()方法来进行文件映射,如下所示:

private static Map createFileMapped() {
   try {
        return ChronicleMap
            .of(Long.class, Point.class)
            .averageValueSize(8)
            .valueMarshaller(PointSerializer.getInstance())
            .entries(10_000_000)
            .createPersistedTo(new File("my-map"));

    } catch (IOException ioe) {
        throw new RuntimeException(ioe);
    }
}

这将创建一个Map,将其内容布局在名为“ my-map”的内存映射文件中,而不是直接内存中。 以下示例说明了如何创建1000万个Point对象并将其全部存储在文件映射图中:

final Map m3 = LongStream.range(0, 10_000_000)
    .boxed()
    .collect(
        toMap(
            Function.identity(),
            FillMaps::pointFrom,
            (u, v) -> {
                throw new IllegalStateException();
           },
           FillMaps::createFileMapped
       )
   );

以下命令显示了新创建的文件:

Pers-MacBook-Pro:target pemi$ ls -lart my-map 
-rw-r--r--  1 pemi  staff  330305536 Jul 10 16:56 my-map

可以看出,该文件约为33 MB,因此每个条目平均占用33个字节。

坚持不懈

当JVM终止时,映射文件仍然存在,从而可以轻松地拾取先前创建的包含其内容的映射。 这非常类似于基本的超快数据库。 这是我们从现有文件开始的方法:

return ChronicleMap
    .of(Long.class, Point.class)
    .averageValueSize(8)
    .valueMarshaller(PointSerializer.getInstance())
    .entries(10_000_000)
    .createOrRecoverPersistedTo(new File("my-map"));

Map将直接可用,包括以前的内容。

Java Map超出RAM限制

内存映射文件的一个有趣方面是,它们可以超过堆和RAM的限制。 文件映射逻辑将确保当前使用的部件按需加载到RAM中。 映射逻辑还将在物理内存中保留已访问映射内存的最新部分,以提高性能。 这发生在幕后,不需要由应用程序本身进行管理。

我的台式计算机是只有16GB内存的较旧的MacBook Pro(是的,我知道那很糟)。 不过,我可以分配一个Map其中包含10亿个条目,它们可能占用33 * 1,000,000,000 = 33 GB内存(我们从上面记得,每个条目平均占用33个字节)。 代码如下:

return ChronicleMap
    .of(Long.class, Point.class)
    .averageValueSize(8)
    .valueMarshaller(PointSerializer.getInstance())
    .entries(1_000_000_000)
    .createPersistedTo(new File("huge-map"));

即使我尝试用2倍于我的RAM大小创建Java Map,代码也可以完美运行,并得到以下文件:

Pers-MacBook-Pro:target pemi$ ls -lart | grep huge-map 
-rw-r--r--   1 pemi  staff  34573651968 Jul 10 18:52 huge-map

不用说,您应该确保要映射的文件位于具有较高随机访问性能的文件系统上。 例如,位于本地SSD上的文件系统。

摘要

ChronicleMap可以映射到外部文件
JVM退出时保留映射的文件
新应用程序可以选择现有的映射文件 ChronicleMap可以容纳的数据多于RAM 映射文件最好放在具有较高随机访问性能的文件系统上

翻译自: https://www.javacodegeeks.com/2019/08/java-chroniclemap-super-ram-maps.html

你可能感兴趣的:(java,python,linux,大数据,jvm)