Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/145.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ boost多索引容器和内存碎片_C++_Boost_Boost Multi Index_Memory Fragmentation - Fatal编程技术网

C++ boost多索引容器和内存碎片

C++ boost多索引容器和内存碎片,c++,boost,boost-multi-index,memory-fragmentation,C++,Boost,Boost Multi Index,Memory Fragmentation,我在服务器中使用MIC作为LRU缓存,它已经取代了list/map LRU,因为我怀疑这是导致一些无法解释的内存占用的原因。内存泄漏是不可能的,至少没有工具发现任何泄漏以及代码检查。自从我开始使用麦克风以来,图像得到了改善(这是内存碎片的唯一证据),但还不够。我们谈论的是几Gb的缓存,每天有数百万条记录从中弹出。两到三周后,问题变得显而易见——如果我清空缓存,进程仍会保留无法解释的2-3Gb内存。 我的容器非常简单: typedef std::pair<Key, T> Element

我在服务器中使用MIC作为LRU缓存,它已经取代了list/map LRU,因为我怀疑这是导致一些无法解释的内存占用的原因。内存泄漏是不可能的,至少没有工具发现任何泄漏以及代码检查。自从我开始使用麦克风以来,图像得到了改善(这是内存碎片的唯一证据),但还不够。我们谈论的是几Gb的缓存,每天有数百万条记录从中弹出。两到三周后,问题变得显而易见——如果我清空缓存,进程仍会保留无法解释的2-3Gb内存。
我的容器非常简单:

typedef std::pair<Key, T> Element;
    typedef mic::multi_index_container<
        Element,
        mic::indexed_by<mic::sequenced<mic::tag<struct Seq>>,
                        mic::hashed_unique<mic::tag<struct Hash>, mic::member<Element, const Key, &Element::first>>>>
        item_list;
typedef std::pair元素;
typedef麦克风::多索引容器<
元素,
麦克风::索引用户>
项目清单;
它使用
erase
push_front
插入新条目(或覆盖旧条目),然后根据需要从尾部弹出元素。问题是是否值得尝试使用
replace
relocate
而不是
push_front


UPDATE001:好的,新版本已经启动并运行,我看到重新配置显著改善了这种情况,3周后的内存占用比没有更改的机器上的内存占用少约1/1.5 Gb。现在它部署在全球所有机器上。作为第二阶段,缓存失效机制有许多变化。更少的弹出和重新插入也会改善这种情况(如果真的是内存碎片)

我们也经历过同样的事情。 我编写了一个小测试程序,它使用300个线程的缓存。它保持
insert
ing和
erase
ing的速度大约为200k(insert+erase)/sec,我在周末运行了它。 我通过pmap-x total RSS检查了内存使用情况

pmap -x [pid] | tail -n1 | awk '{print $4}'
在一分钟的分辨率中,我们可以看到,在加载缓存之前,内存消耗在0到4.7GB之间是线性的,此后它以对数速度不断增加。如图所示。(缓存已满需要14分钟)。


另一件有趣的事情是,pmap-x报告了大量65536k的虚拟内存块正在加载(因此理论上可能存在这种过度内存使用的最大值),但如果我从一个线程执行相同的操作,测试程序会分配一个4.7GB的块,并且在缓存满后,内存使用是恒定的。

我们也经历过同样的事情。 我编写了一个小测试程序,它使用300个线程的缓存。它保持
insert
ing和
erase
ing的速度大约为200k(insert+erase)/sec,我在周末运行了它。 我通过pmap-x total RSS检查了内存使用情况

pmap -x [pid] | tail -n1 | awk '{print $4}'
在一分钟的分辨率中,我们可以看到,在加载缓存之前,内存消耗在0到4.7GB之间是线性的,此后它以对数速度不断增加。如图所示。(缓存已满需要14分钟)。


另一件有趣的事情是,pmap-x报告了大量65536k的虚拟内存块正在加载(因此理论上可能存在这种过度内存使用的最大值),但如果我从一个线程执行相同的操作,测试程序会分配一个4.7GB的块,并且在缓存满后,内存使用是恒定的。

只是问一下-您知道malloc/free是如何工作的,以及为什么进程内存在分配后从不释放并不重要?alloc/free如何工作并不重要,因为它们不负责内存的分配/释放,操作系统内存管理器才是。在这种特殊情况下,VirtualAllocEx将启动,决定将分配多少内存(是的,即使这不是alloc完成的),实际上释放并不能保证内存将实际释放回操作系统。但是,您可以强制操作系统重新获得释放,但不能释放回操作系统内存\right。。。那么,为什么进程的内存占用没有下降呢?还是我误解了这个问题?当1.2Gb是初始分配时,它会下降,比如说从7Gb下降到3Gb。然后我强迫操作系统尝试释放进程持有的所有未分配页面,它不起作用(在某种程度上起作用),所以我猜这是碎片。我没有证据,但将LRU的一种实现更改为另一种实现改进了进程的内存状态,而MIC以较少的内存碎片整理而闻名,因此,我想这加强了我的理论。因此,也许缓存对象的自定义分配器(保证缓存对象始终存储在保留给它们的页面中)会对您有所帮助?只是问问-您是否知道malloc/free是如何工作的,为什么进程内存一经分配就不会释放并不重要?alloc/free如何工作并不重要,因为它们不负责内存的分配/释放,而OS内存管理器负责。在这种特殊情况下,VirtualAllocEx将启动,决定将分配多少内存(是的,即使这不是alloc完成的),实际上释放并不能保证内存将实际释放回操作系统。但是,您可以强制操作系统重新获得释放,但不能释放回操作系统内存\right。。。那么,为什么进程的内存占用没有下降呢?还是我误解了这个问题?当1.2Gb是初始分配时,它会下降,比如说从7Gb下降到3Gb。然后我强迫操作系统尝试释放进程持有的所有未分配页面,它不起作用(在某种程度上起作用),所以我猜这是碎片。我没有证据,但将LRU的一种实现更改为另一种实现改进了进程的内存状态,而MIC以较少的内存碎片整理而闻名,因此,我想这加强了我的理论。因此,也许缓存对象的自定义分配器(保证缓存对象始终存储在保留给它们的页面中)会对您有所帮助?顺便说一句,我们完全放弃了LRU的东西,转而使用未绑定的无序映射。嗯,我们没有