Memory pool

自从fcitx的内核从古老的gbk转向了utf8之后,自带拼音和码表的字符串就带来了一些问题。

首先情况是这样的在我的系统上,fcitx的自带拼音加载后将占用28MB的内存,考虑下的话,其中有个 (2int+2pointer)*词数的数据结构,其次是词本身,有约4MB,词总数约20万。那么估计一下的话拼音应该占用约8.5M。考虑刚刚启动不加载的时候,占用约6M,总计应该在14M左右。那多出来的14M都干啥去了呢?(并无内存泄露)

之前也一直没有关注这件事情,不过在前几天在 @henryhu 的建议下增加了一个Memory pool的实现。这个实现非常naive,乃至于不能单独释放申请的内存(只能整体释放)。不过对于fcitx自身拼音和码表的实现这个情况来说,是一个非常合适的选择。

首先有兴趣的人可以来做一个实验,写一个for循环,每次使用malloc申请1字节,循环申请1M次。然后看看操作系统的内存使用量。然后修改下,每次申请16字节,循环申请64k次,总量也是1MB,然后再看看操作系统内存使用量。

具体实现如下,内存不足时默认每次申请8k字节的内存块,如果一次申请超过8k就申请8k的2的n次方那么大的内存。每个块使用一个offset标记里面当前free的位置,当offset和容量的差距小于某个threshold的时候,就将其从可申请的list中移除,保证在遍历候选内存块的列表时的效率,那些不使用的部分成为可以忽略的内存碎片。(实际设定threshold = 16,16相比 8k 可忽略不计)

对于码表和拼音来说,其中的数据是几乎不用单独释放的,这正好可以采用这种naive的实现(而不是使用比较复杂的full functional的memory pool)。

那么最终的效果就是在我的系统上fcitx自带拼音加载后使用内存达到14MB,符合最开始的预期使用。

Ref:

http://code.google.com/p/fcitx/issues/detail?id=133

http://en.wikipedia.org/wiki/Memory_pool

This entry was posted in fcitx development. Bookmark the permalink.

8 Responses to Memory pool

  1. Iven says:
    Firefox 9.0.1 GNU/Linux x64

    虽然不懂,但是看起来很厉害的样子…… XD

  2. ayanamist says:
    Firefox 9.0.1 Windows 7

    还是没讲明白那14M到哪里去了……

  3. csslayer says:
    Firefox 11.0a2 Windows 7

    @ayanamist 被内存管理和对齐之类的消耗掉了。

  4. ayanamist says:
    Firefox 9.0.1 Windows 7

    @csslayer
    好可怕,内存管理能消耗这么多么!

  5. ayanamist says:
    Firefox 9.0.1 Windows 7

    @csslayer
    另外突然发现老K居然是用Windows回复我的……orz……老K你的Chakra呢……

  6. 右京样一 says:
    Firefox 9.0.1 GNU/Linux

    原来如此……当时看C++教材的时候确实提过申请内存的机制……话说实现方法貌似是个环形链表来着?

  7. 右京样一 says:
    Firefox 9.0.1 GNU/Linux

    这个“有兴趣的人”真是坑爹啊……我试了一个字节一个字节申请1兆内存,结果硬盘狂转,操作卡死,我勉强进了命令行杀掉了进程才慢慢恢复……

    后来我又试了试别的操作,得出的结论是:没事千万别写一兆次的循环……

  8. Yue Liu says:
    Google Chrome 16.0.912.75 GNU/Linux x64

    测试一下UA。

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.