SKIA源代码发现的两处内存泄露及解决方法!

warpo warpo 墨衍会员 · AI 创作全网分发 墨衍智能分发 通过墨衍一键同步至各平台 可同步平台 CSDN微信公众号微博知乎掘金百家号博客园抖音小红书 你的文章也可以这样分发 墨衍会员 ¥399起/年,写一次发全网 我也要 + 加入社区
最近在移植第三方SKIA图形库.发现有内存泄露.简述如下.

SKIA源代码有内存泄露的解决办法.

1) 源码SkMemory_stdlib.cpp中将函数 static SkMutex& get_block_mutex() 修改如下:

static SkMutex& get_block_mutex() {

//fixed by warpo. ADD 35-40.
static SkMutex gbm;
static SkMutex* gBlockMutex = &gbm;
if (NULL == gBlockMutex ) {
gBlockMutex = new SkMutex;
}
return *gBlockMutex;

//原始代码如下:
//static SkMutex* gBlockMutex;
//if (NULL == gBlockMutex) {
// gBlockMutex = new SkMutex;
//}
//return *gBlockMutex;
}

该错是new SkMutex之后未释放内存.



2).源码SkGlyphCache.cpp中的内存泄露.

为SkGlyphCache类增加一个静态函数,然后在程序结束时调用即可:

size_t SkGlyphCache::freeGlyphCache_Globals(/*SkGlyphCache_Globals* globals, size_t bytesNeeded*/)
{

SkGlyphCache_Globals& globals = FIND_GC_GLOBALS();
globals.validate();

size_t bytesFreed = 0;
int count = 0;

// don't do any "small" purges
//size_t minToPurge = globals.fTotalMemoryUsed >> 2;
//if (bytesNeeded < minToPurge)
// bytesNeeded = minToPurge;

SkGlyphCache* cache = FindTail(globals.fHead);
while (cache != NULL ) {
SkGlyphCache* prev = cache->fPrev;
bytesFreed += cache->fMemoryUsed;

#ifdef USE_CACHE_HASH
unsigned index = desc_to_hashindex(cache->fDesc);
if (cache == globals.fHash[index]) {
globals.fHash[index] = NULL;
}
#endif

cache->detach(&globals.fHead);
SkDELETE(cache);
cache = prev;
count += 1;
}

SkASSERT(bytesFreed <= globals.fTotalMemoryUsed);
globals.fTotalMemoryUsed -= bytesFreed;
globals.validate();

#ifdef SPEW_PURGE_STATUS
if (count) {
SkDebugf("purging %dK from font cache [%d entries]\n",
(int)(bytesFreed >> 10), count);
}
#endif

return bytesFreed;
}

在WIN平台下(其它平台未验证)引起该内存泄露的原因是SKIA使用的字体缓存机制,当绘制文字时都会new一些缓存,其中globals是全局静态的一个保存字体缓存数据的结构,但笔者使用源码时发现未释放.所以需要手动调用释放.

3). 需要手动调用类的SkTypefaceCache的purge方法清空缓存.该问题也是由于NEW后未释放造成的.具体流程不详说.可以自己跟踪调试.
...全文
评论 5
收藏 已收藏
分享
返回顶部
warpo
Android 80,489 成员 91,375 内容