【问题标题】:Allocate huge classes in virtual memory c++在虚拟内存c ++中分配巨大的类
【发布时间】:2017-09-19 05:34:37
【问题描述】:

我有一个大小为 2KB 的类(表示树中的一个节点),当我的程序运行时,它分配了大约 60,000 个节点,这些节点占用了 120 MB 的内存。

我想为我的应用减少这种内存占用。为此,我试图找到一种方法,使内存不是在堆中分配,而是在虚拟内存中分配。

我已经为此查看了 mmap 文件。但是,我有以下疑问:

  1. 我查看了类的序列化(使用 boost),然后将其存储在内存映射文件中。但是类很大,可能无法序列化
  2. 然后我遇到了 basic_managed_shared_memory(再次提升)。但我不知道如何在这个托管内存中分配我的类的新实例。也欢迎在这里提供任何帮助。

所以,我关心的是如何在有或没有内存映射文件的情况下在虚拟内存中分配我的类的新实例。

P.S.:该应用程序将在 iOS 上运行。

【问题讨论】:

  • 为什么不将对象存储在 NoSQL 数据库中?只加载你需要的东西。不过,您可能必须能够序列化整个对象。
  • “序列化可能不可能” 为什么不呢?如果不方便,序列化应该总是可行。
  • 您可以使用支持 iOS 的高性能键值存储数据库,例如 [LMDB][1](Lightning Memory-Mapped Database)来存储您的 2 KB 节点序列化。 2 KB 块的序列化应该很容易归档。
  • 如果数据不是很随机,也可以使用内存压缩技术。
  • 实施压缩/数据库存储后,您会发现设备电池消耗得更快。 :-]

标签: c++ ios memory-management boost virtual-memory


【解决方案1】:

我不是 iOS 程序员,但我会写一个独立于平台的响应,希望这会有所帮助。

第一点: 2KB * 60,000 个节点 = 120 MB

如果您使用标准分配器 - 这是不正确的。结果大小可以更大。发生这种情况是因为标准分配器需要保存许多内部信息以涵盖其使用的所有选项。

如果你使用自己的分配器 - 它可以是真的也可以不是。这取决于如何实现自己的分配器。例如,如果使用某种线性分配器并且不在一个操作中分配对象,你会得到一些内存开销(当然它会小于标准分配器)

如果您使用直接 api 调用(mmap)通过一个操作分配所有数据 - 在这种情况下,您将使用本机 120 MB。

第二点:在外部数据库中保存(或不保存)一些数据

正如评论中所指出的,它有助于减少应用程序的虚拟内存。

而且您甚至不需要将所有内容都存储在数据库中。您可以实现类似交换机制之类的东西,并仅在内存中保留您目前需要的内容。

但要小心。一切都有它的代价。例如,如果您经常在数据库中读取/写入数据,这可能会导致 CPU/电池利用率。

第三点:一些“技巧”

  • 如果树的两个(或更多)节点可以保存相同的信息,您可以 分配一个节点,多处引用他

  • 如果在节点中某个大字节序列可以为零(或其他值),您可以使用类型化的 chucnks 实现特殊的数据结构。在这种情况下,一种类型的块可以是被视为零字节序列的小对象。

第四点堆/虚拟内存、mmap、内存映射文件

根据我的经验,所有需要大量内存使用的任务,总是通过虚拟内存 api(mmap, VirtualAlloc) 手动管理。如果您不需要共享数据,请不要使用内存映射文件

PS

我写了一些关于你的问题的一般信息,因为你没有指定你的任务。如果您提供更多信息,也许有更适合您的解决方案

【讨论】:

    猜你喜欢
    • 2012-12-30
    • 2023-03-06
    • 2011-03-08
    • 2013-01-24
    • 1970-01-01
    • 2012-12-21
    • 2020-02-19
    • 2011-09-26
    • 2013-09-15
    相关资源
    最近更新 更多