如何缓存1000个大型C++对象
how to cache 1000s of large C++ objects
环境:Windows 8 64位、Windows 2008服务器64位Visual Studio(专业版)2012 64位
列表L//我在程序中缓存了1000个大型CMyObject,这些对象由我的windows服务程序中的不同线程共享。
对于我们的SaaS中间件产品,我们在内存中缓存1000个大型C++对象(只读常量对象,每个对象的大小约为4MB),这会耗尽系统的内存。我们可以将磁盘文件(或其他由操作系统管理的持久机制)与C++对象相关联吗?不需要共享/进程间通信。
如果磁盘文件在整个过程(我们的windows服务程序)中都能工作,那么它就足够了。只读常量C++对象由同一windows服务中的不同线程共享。
我甚至考虑使用对象数据库(如mongoDB)来存储对象,然后在每次使用时加载/卸载这些对象。虽然比读取序列化文件快(希望如此),但它仍然会破坏性能。
其目的是出于性能原因保留C++对象的缓存,并避免每次都必须加载/卸载序列化的C++对象。如果这个磁盘文件是操作系统管理的,并且需要对我们的代码进行最小的调整,那就太好了。
提前感谢您的回复。
操作系统以您描述的方式管理的唯一东西就是交换文件。您可以创建一个单独的应用程序(将其称为"缓存助手"),它将所有对象加载到内存中并等待请求。由于操作系统不使用内存页面,因此操作系统最终会将页面转移到交换文件中,只有在需要时才会调用该文件。可以通过命名的管道或插座与应用程序进行通信。
这种方法的缺点是,这种缓存的性能将高度不稳定,并且可能降低整个服务器的性能。
我建议您编写自己的缓存算法/应用程序,因为您稍后可能需要调整其属性。
一个解决方案当然是简单地加载每个对象,并让操作系统根据需要处理从磁盘交换到磁盘的问题。(或者动态加载,但除非对象完全被破坏,否则永远不要丢弃)。如果存在比其他对象更频繁使用的对象数量,则这种方法将很好地工作。从swapspace加载几乎可以肯定比你能写的任何东西都快。例外情况是,如果您事先知道哪些对象下一步更有可能或不太可能被使用,并且可以在内存不足的情况下"抛出"正确的对象。
当然,你也可以使用内存映射文件——这将允许你像读取内存一样读取和写入文件(当内存可用时,操作系统会将内容缓存在RAM中)。在WIndows上,您将使用CreateFileMapping
或OpenFileMapping
创建/打开文件映射,然后使用MapViewOfFile
将文件映射到内存中。完成后,使用UnmapViewOfFile
"取消映射"内存,然后使用CloseHandle
关闭FileMapping。
关于文件映射,唯一担心的是它下次可能不会出现在内存中的同一地址,所以你不能在文件映射中有指针,下次加载与二进制相同的数据。当然,每次都创建一个新的文件映射会很好。
因此,您的数千个大型对象都有构造函数、析构函数、虚拟函数和指针。这意味着你不能轻易地将它们分页出来。不过,操作系统可以帮你做到这一点,所以你最实用的方法就是添加更多的物理内存,可能是SSD交换卷,并使用64位地址空间。(我不知道在你的操作系统上有多少是可寻址的,但大概足以容纳你的~4G个对象)。
你的第二个选择是找到一种方法来节省一些内存。这可能是使用专门的分配器来减少空闲,或者删除间接层。你没有提供足够的关于你的数据的信息,我无法对此提出具体建议。
第三种选择,假设您可以将程序放入内存中,则只是加快反序列化的速度。你能把格式改成更有效解析的格式吗?你能按需快速反序列化对象吗?
最后一个选项,也是大多数工作,是手动管理交换文件。作为第一步,将大量多态类拆分为两个是明智的:多态轻量级(每个具体子类型有一个实例)和扁平聚合上下文结构。此聚合是您可以安全地交换地址空间的部分。
现在,您只需要一个内存映射的分页机制,某种缓存跟踪当前映射的页面,可能是一个智能指针用页面+偏移量取代原始指针,可以按需映射数据,等等。同样,您还没有提供足够的数据结构和访问模式信息来提出更详细的建议。
- 删除一个线程上有数百万个字符串的大型哈希映射会影响另一个线程的性能
- 如何实现高效的算法来计算大型数据集的多个不同值?
- 如何在C++中写入 1000 个文件时有效地缓冲
- 如何在没有同步的情况下使用多个线程(2、4,8、16 个线程)在循环(10,100、1000 个周期)中打印字符串?
- 并行阅读多个大型CSV文件
- C# 选项,以最好地使用具有 1000 个函数的 C++ DLL
- QTableView 在 1000 个可见单元格下性能缓慢
- 初始化 1000 个地图元素
- 连接两个大型 QVector 并对其进行排序的最快方法 (C++/Qt)
- 字符串输入超过1000个字符时执行挂起
- 如何在不阻塞UI的情况下在QGraphicsScene中移动1000个项目
- 如何输入包含少于1000个单词的带有空格和标点符号的文本
- 找出给定长度为100的字符串中的1000个的最小唯一子字符串的长度
- 如何缓存1000个大型C++对象
- 编写程序生成1000个0-49范围内的随机整数.(c++)
- Pthreads池,保持1000个打开线程,pthread_create()返回11
- 生成一个不同于数组中1000个元素的新元素
- 将文件的前1000个字符读入缓冲区,将换行符转换为 ,并将字符串的地址位置存储为char*[]
- 对1000个整数的数组进行排序
- 使用unordered_map删除两个大型文本文件中的重复项