×

Loading...
Ad by
  • 推荐 OXIO 加拿大高速网络,最低月费仅$40. 使用推荐码 RCR37MB 可获得一个月的免费服务
Ad by
  • 推荐 OXIO 加拿大高速网络,最低月费仅$40. 使用推荐码 RCR37MB 可获得一个月的免费服务

请教高手:有自建memory pool的,请问如何管理内存碎片

我们知道系统提供的动态内存分配new-delete; malloc-free,系统会完成内存碎片的整理。
自建的memory pool就要自己进行了。

memory pool重载new,delete,从自建的memory pool中动态分配内存。有可能产生内存碎片
例如new-delete产生了4个50k的fragment,共有200k的free memory,此时allocate 100k的内存会失败
什么算法处理?
我想了建立链表,存储pool中的偏移量,size和应用中申请内存的指针的指针。线程idle时进行内存整理,DEFRAGMENT会涉及内存块的移动,就要修改应用中的pointer。 defragment后通过指针的指针修改应用中指针的指向。
问题是重载new,应用中不会传递给我他申请内存的指针:
调用重载new,
void * p =new(size);
我在new中返回一个指针指向pool中。
但是我不知道void **p,无法在链表中存储*p的地址。整理内存时,无法修改应用中的*p的值
我想除非改变new的形式:new(size, **p)
诸大侠有什么建议??
Report

Replies, comments and Discussions:

  • 工作学习 / 专业技术讨论 / 请教高手:有自建memory pool的,请问如何管理内存碎片
    我们知道系统提供的动态内存分配new-delete; malloc-free,系统会完成内存碎片的整理。
    自建的memory pool就要自己进行了。

    memory pool重载new,delete,从自建的memory pool中动态分配内存。有可能产生内存碎片
    例如new-delete产生了4个50k的fragment,共有200k的free memory,此时allocate 100k的内存会失败
    什么算法处理?
    我想了建立链表,存储pool中的偏移量,size和应用中申请内存的指针的指针。线程idle时进行内存整理,DEFRAGMENT会涉及内存块的移动,就要修改应用中的pointer。 defragment后通过指针的指针修改应用中指针的指向。
    问题是重载new,应用中不会传递给我他申请内存的指针:
    调用重载new,
    void * p =new(size);
    我在new中返回一个指针指向pool中。
    但是我不知道void **p,无法在链表中存储*p的地址。整理内存时,无法修改应用中的*p的值
    我想除非改变new的形式:new(size, **p)
    诸大侠有什么建议??
    • google "placement new"
      • 不用google,这个语法我熟悉
        但是还是没有解决我的问题
        我建立了一个1M的memory pool,随后建立了20个50k的对象。
        运行中,我delete了其中4个长得最难看或是成绩最差的(我这样说是指在我delete前,即使我先排序,再进行placemen new也无法保证这四个对象连续,因为删除的标准未定)对象,还是无法allocate 100k内存给另一个大对象。

        或者我仅仅熟悉语法,对placement new的应用还有没有理解的地方?请帮忙给个解释?多谢
    • 苹果OS以前使用双指针,不直接将内存地址返回给程序,而是维护一个地址列表,然后将地址列表中元素的地址返回给程序,这样OS可以在空余期间收集碎片,而程序需要dereference两次来取得实际地址。OS同时提供API给程序来临时锁定某块内存。
      • 这是一个好方法,代价是要重载取址和指针运算符 &和×
        • 那要看你的内存管理器或者wrapper class的实现了,反正理论上是可行的,把锁做好了也不会出问题。反正记得当初学C不久,指针还没搞熟,看到苹果OS程序中到处是**心理发虚...
          • Agree
      • 多谢,我想这个思路可以实现
        在memory pool中建立一个Memory_virtual_table存储在pool中的地址
        new返回MVTBL中的地址
        defragment整理pool和VMTBL中指针值。应用程序调用指针指向的内存内容不变。
        代价是&和*是一定要重载的,如果仔细研究,数组下标[]也是要重载
        实现起来有一定困难,不过起码是可以实现的方案。毕竟自己写个memory pool不能指望100%达到系统的功能