簡體   English   中英

boost interprocess vector不會釋放共享內存

[英]boost interprocess vector does not deallocate shared memory

我正在使用boost :: interprocess在linux上的進程之間共享復雜的數據結構。 它主要工作,但我的共享內存慢慢泄漏每次更新共享數據。

經過一些調試后,我能夠提出相對較短的方法來重現這種行為:

#include <iostream>

#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/allocators/allocator.hpp>
#include <boost/interprocess/containers/vector.hpp>
#include <boost/interprocess/containers/string.hpp>


using UniversalAllocator = boost::interprocess::allocator
    < void
    , boost::interprocess::managed_shared_memory::segment_manager >;

using CharAllocator = boost::interprocess::allocator
    < char
    , boost::interprocess::managed_shared_memory::segment_manager >;

using ShmString = boost::interprocess::basic_string<char,   std::char_traits<char>, CharAllocator>;

struct Struct1
{
    Struct1(UniversalAllocator allocator)
        : member(allocator)
    {}
    struct Struct2
    {
        Struct2(UniversalAllocator allocator)
            : vector_member(allocator)
        {}
        struct Struct3
        {
            Struct3(UniversalAllocator allocator)
                : first(allocator)
                , second(allocator)
            {}
            ShmString first;
            ShmString second;
        };

        using Struct3Allocator = boost::interprocess::allocator
            < Struct3, boost::interprocess::managed_shared_memory::segment_manager >;
        using Structs3 = boost::interprocess::vector<Struct3, Struct3Allocator>;

        Structs3 vector_member;

    } member;
};

using Struct1Allocator = boost::interprocess::allocator
    < Struct1, boost::interprocess::managed_shared_memory::segment_manager >;

using Struct1Vector = boost::interprocess::vector
    < Struct1, Struct1Allocator>;


int main(void)
{
      boost::interprocess::managed_shared_memory segment(
          boost::interprocess::create_only,
          "TEST_MEMORY_LEAK",
          1500);
      std::cout << segment.get_free_memory() << std::endl;
      while(1)
      {
          Struct1Vector svector(segment.get_segment_manager());
          Struct1 selement(segment.get_segment_manager());
          svector.push_back(selement);
          std::cout << segment.get_free_memory() << std::endl;
      }
      return 0;
}

內存在push_back調用內部分配,但在離開作用域時僅部分解除分配。 結果是:

$ g++ --std=c++11 -Wall -pthread -c memory_leak.cpp -o memory_leak.o
$ g++ memory_leak.o -o memory_leak -pthread -lrt
$ ./memory_leak
1276
1180
1132
1084
1036
988
940
892
844
796
748
700
652
604
556
508
460
412
364
316
268
220
172
124
76
28
terminate called after throwing an instance of 'boost::interprocess::bad_alloc'
  what():  boost::interprocess::bad_alloc
Aborted

奇怪的是,如果我用1000(而不是1500)替換共享內存大小,循環真的是無窮無盡的(它將最終打印24次無限次,所以內存泄漏到最后一刻然后......停止?)。

我正在使用boost 1.54和gcc 4.8.4如果重要,任何幫助將不勝感激,我有點想法:(

共享內存不像堆,但它不是你的堆。 共享意味着鎖定和鎖定是昂貴的。 您會注意到,managed_buffer / managed_mapped_file / managed_shared_memory段管理器將盡可能晚地回收內存(僅在分配失敗時才可能)。

如果此時可用內存開銷太小,則可能沒有足夠的空間來滿足連續分配(因此您將優先考慮分配失敗,作為泄漏的證據。實際上它是碎片的證明)。

我繼續實現了自己的內存管理算法(作為rbtree_best_fit的一個瘦包裝器,它是默認的,因此在上面的示例中使用)。 我最終看到上面的代碼在push_back上分配了兩個段 - 一個非零長度和一個零長度,只解除前一個。 這對我來說似乎不對,所以我搜索了推特網站的解釋,並找到了我認為的問題 升級系統升級到1.55后,上面打印1228無限次數(大概是正確的行為)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM