最近在移植第三方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后未释放造成的.具体流程不详说.可以自己跟踪调试.
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后未释放造成的.具体流程不详说.可以自己跟踪调试.
解决方案 »
- 设置了开机自启动,启动不了
- 想买一个电脑,想买苹果,感觉不怎么适合编程,求介绍。。。
- gesture.toBitmap 之后,如何在形成的bitmap上的手势开始点画个圆圈。表明是开始点。
- 请问在Activity中如何终止由另一个Activity启动的服务?
- 急求急求!!!
- 关于Receiver被调用时处于哪个进程和线程的问题
- 用Eclipse导入android工程时,中文字符老是出现乱码。
- 两小球碰撞后的移动方向应该怎么计算啊
- SoapFault - faultcode: 'a:ActionNotSupported' faultstring: '由于 ContractFilter 在
- H5嵌入到第三方app里面使用拍照功能
- android webview
- 怎样让WindowManager加上的view和周围没被view挡住的控件都获得焦点
有个疑问,get_block_mutex() 被调用的地方都是
SkAutoMutexAcquire ac(get_block_mutex()); //不知道ac 这个函数啥意思而SkAutoMutexAcquire的析构函数中有
~SkAutoMutexAcquire()
{
if (fMutex)
fMutex->release();
}那么SkAutoMutexAcquire在释放时 是不是也会释放这个指针
而源码中
static SkMutex* gBlockMutex;
if (NULL == gBlockMutex) {
gBlockMutex = new SkMutex;
}
return *gBlockMutex
静态局部变量至程序结束时都会保存第一次new SkMutex的指针变量,但结束程序并未释放这个指针变量所指对象.
get_block_mutex() 被调用的地方就是SkAutoMutexAcquire ac(get_block_mutex());
ac并不是函数,是SkAutoMutexAcquire 类对象.括号内的是SkAutoMutexAcquire类对象ac的构造函数的参数.这个参数是get_block_mutex(),返回的就是new SkMutex.
skia在decode一张图片时,如何让其尽量少的占用内存,图片显示的质量差点没关系。