0

我有一个像这样的旧结构类:typedef vector<vector<string>> VARTYPE_T;它作为单个变量工作。此变量可以保存从列表中的一个值到表格等数据。对于坐标 (x,y,z),大多数值是 long、double、string 或 double [3]。我只是根据需要转换它们。变量在这样的映射中管理:map<string,VARTYPE_T *>字符串包含变量名称。当然,它们被包裹在类中。我也有一棵节点树,其中每个节点都可以保存这些变量映射之一。

为此使用 VS 2008 SP1,我检测到大量内存碎片。检查 stlport,stlport 似乎更快(20%)并且使用更少的内存(30%,对于我的测试用例)。

所以问题是:用快速正确使用的内存来解决这个要求的最佳实现是什么?我应该像池分配器一样编写自己的分配器。你会怎么做?

提前致谢,

豪伊

4

1 回答 1

0

更改typedef vector<vector<string>> VARTYPE_T;typedef deque<deque<string>> VARTYPE_T;检查是否仍有内存碎片。

顺便问一下,你如何用 VS 2008 SP1 测量它?

更新: 我知道 HP 如何处理 HP-UX 内存碎片。经过一番搜索,我发现了一个有趣的链接Low-fragmentation Heap。这是一个引用:The low-fragmentation heap (LFH) helps to reduce heap fragmentation。对我来说这很有趣,因为它类似于 HP 处理内存碎片的方法,当然从它的描述来看。我认为(除了使用双端队列)尝试检查是另一个好主意。`

更新 2: 1)速度。你之前没有告诉过速度,所以我没有任何指导可以给你一些好的建议。我也不知道您的程序在执行时大部分时间都花在了哪里。

如果您认为它主要花时间将字符串转换为 long 和 double,那么您只需执行一次此转换并在访问变量值时使用它。可能不存储字符串而是存储实际值是个好主意。例如在联合或 Boost.Variant 中。如果您认为变量缺少可以快速访问其值的索引,您应该添加这些索引。

2) 内存使用。您是否真的在编写一个运行了好几天的服务器应用程序并且应该非常关心它的内存消耗?然后我已经告诉过你,Low-fragmentation Heap在 Windows 上使用并尝试使用小于 16K 的块大小。也摆脱内存泄漏。当然检查它,但据我了解Low-fragmentation Heap必须处理你的消息。

3) 如果您编写服务器应用程序,则 std::vector 有时不是一个好的选择。它在一个块中分配内存。如果超过 16K,这可能会导致内存碎片。

4) 最后,看看来自 HP-UX 的关于内存分配的良好报告是什么样子的(为了找到内存碎片):

Actual Heap Usage:
    Heap Start  =   0x60000000000fea38
    Heap End    =   0x6000000026580000
    Heap Size   =   642258376 bytes

Outstanding Allocations:
    251948524 bytes allocated in 4239425 blocks
                              Detailed Report

-------------------------------------------------------------------------
65343264 bytes in 1361318 blocks (25.94% of all bytes allocated)
These range in size from 48 to 48 bytes and are allocated
#0  stlp_std::__malloc_alloc::allocate(unsigned long&)   from ./libstlport.so.5.1
#1  boost::multi_index::detail::ordered_index<boost::multi_index::identity<csubs::clnt_tax_hist_t>, stlp_std::less<csubs::clnt_tax_hist_t>, boost::multi_index::detail::nth_layer<1, csubs::clnt_tax_hist_t, boost::multi_index::indexed_by<boost::multi_index::ordered_non_unique<boost::multi_index::identity<csubs::clnt_tax_hist_t>, mpl_::na, mpl_::na>, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, hrs_allocator::counting_allocator<csubs::clnt_tax_hist_t, (hrs_allocator::allocator_enums)9> >, boost::mpl::vector0<mpl_::na>, boost::multi_index::detail::ordered_non_unique_tag>::insert(csubs::clnt_tax_hist_t const&)   at _alloc.h:381



-------------------------------------------------------------------------
47510512 bytes in 848402 blocks (18.86% of all bytes allocated)
These range in size from 56 to 56 bytes and are allocated
#0  stlp_std::__malloc_alloc::allocate(unsigned long&)   from ./libstlport.so.5.1
#1  csubs::cache_impl<csubs::subs_data_t, csubs::search_policy_range<false>, csubs::erase_policy_range, hrs_allocator::counting_allocator<csubs::subs_data_t, (hrs_allocator::allocator_enums)5>, boost::multi_index::multi_index_container<csubs::subs_data_t, boost::multi_index::indexed_by<boost::multi_index::ordered_non_unique<boost::multi_index::identity<csubs::subs_data_t>, mpl_::na, mpl_::na>, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, hrs_allocator::counting_allocator<csubs::subs_data_t, (hrs_allocator::allocator_enums)5> > >::put(csubs::subs_data_t const&)   at _alloc.h:381
#2  csubs::db_cache_loader<csubs::cache_impl<csubs::subs_data_t, csubs::search_policy_range<false>, csubs::erase_policy_range, hrs_allocator::counting_allocator<csubs::subs_data_t, (hrs_allocator::allocator_enums)5>, boost::multi_index::multi_index_container<csubs::subs_data_t, boost::multi_index::indexed_by<boost::multi_index::ordered_non_unique<boost::multi_index::identity<csubs::subs_data_t>, mpl_::na, mpl_::na>, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, hrs_allocator::counting_allocator<csubs::subs_data_t, (hrs_allocator::allocator_enums)5> > >, csubs::ctrl_loader_nocheck>::operation()   at cache_subs_loaders.h:121
#3  csubs::group_subs_cache::load_caches_from_db(db_date const&, csubs::cache_options const&, otl_connect&, csubs::cache_stat*)   at ./caches/cache_subs_caches.cpp:1452

等等。

于 2010-03-09T07:36:02.090 回答