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

warpo 2011-09-14 06:20:10
最近在移植第三方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后未释放造成的.具体流程不详说.可以自己跟踪调试.
...全文
488 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
qthsrs232 2012-05-30
  • 打赏
  • 举报
回复
只会修修改改
csuhanyong 2011-12-14
  • 打赏
  • 举报
回复
楼主问下,
skia在decode一张图片时,如何让其尽量少的占用内存,图片显示的质量差点没关系。
warpo 2011-09-14
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 l417584711 的回复:]
不懂C
有个疑问,get_block_mutex() 被调用的地方都是
SkAutoMutexAcquire ac(get_block_mutex()); //不知道ac 这个函数啥意思。。。

而SkAutoMutexAcquire的析构函数中有
~SkAutoMutexAcquire()
{
if (fMutex)
fMutex->release();
}……
[/Quote]
之前我和你一样,注意到它的析构,不过源码里的fMutex->release()并未delete fMutex.你可以去看看内容,它只是做了线程相关的互斥量的解锁.并未释放内存.
而源码中
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.
aSysBang 2011-09-14
  • 打赏
  • 举报
回复
不懂C
有个疑问,get_block_mutex() 被调用的地方都是
SkAutoMutexAcquire ac(get_block_mutex()); //不知道ac 这个函数啥意思。。。

而SkAutoMutexAcquire的析构函数中有
~SkAutoMutexAcquire()
{
if (fMutex)
fMutex->release();
}

那么SkAutoMutexAcquire在释放时 是不是也会释放这个指针
passself 2011-09-14
  • 打赏
  • 举报
回复
楼主厉害,修改framework的代码
内容概要:本文研究了计及碳排放的多微网电能交互分布式运行策略,提出了一种基于交替方向乘子法(ADMM)的优化方法,旨在实现多微电网系统在满足能源供需平衡的同时降低碳排放。文中构建了包含分布式电源、储能系统、可控负荷及碳排放约束的多微网协同优化模型,通过ADMM算法将全局优化问题分解为各微网子系统独立求解的子问题,实现分布式协同调度,在保障各微网自治性的同时兼顾系统整体的经济性与低碳性。研究通过Matlab代码完成了算法仿真,验证了所提策略在提升能源利用效率、减少碳排放、增强系统鲁棒性与可扩展性方面的有效性,为低碳化、去中心化的能源互联网运行提供了理论支持与实践参考。; 适合人群:具备电力系统分析、优化理论及Matlab编程基础的科研人员、电气工程及相关专业的研究生,以及从事智慧能源、分布式能源系统规划与运行的工程技术人员。; 使用场景及目标:①应用于多微电网系统的分布式能量管理与协同优化调度;②支持“双碳”目标下的低碳电网运行策略设计与政策评估;③为ADMM等分布式优化算法在能源系统中的工程化应用提供完整的模型构建、算法实现与仿真验证案例。; 阅读建议:读者应结合Matlab代码深入理解ADMM算法的迭代流程、拉格朗日函数构造与收敛条件设定,重点关注模型中碳排放因子的引入方式、变量分解机制与子问题求解过程,建议通过调整微网数量、碳价参数及通信拓扑结构进行多场景仿真,以深化对分布式协同机制与环保经济权衡关系的理解。
下载代码方式:https://pan.quark.cn/s/cc130f55eddd BUCK变换器,亦称为降压型转换器,在开关电源技术中属于一种基础电路拓扑,其核心功能在于实现从高电压到低电压的转换,并且在转换过程中确保输出端电压的稳定性。本文的核心内容集中在对BUCK变换器的运行机制进行剖析、阐释电流连续模式(CCM)与断续模式(DCM)之间的差异,并深入探讨这两种模式在稳态下的相互关系,同时研究BUCK变换器的交流等效电路模型以及电压与电流补偿回路的构建方法。BUCK变换器的原理示意图如图1所示,其显著特征在于输出电压值低于输入电压值,输出电流保持连续状态,而输入电流则呈现出脉动特性。变换器的工作过程可以划分为两个主要阶段:在第一个阶段,即开关管导通期间,电感元件负责储存能量,电流呈现出线性增长的趋势,并且同时向负载提供能量;在第二个阶段,即开关管截止期间,电感通过二极管实现能量的续流,电流则表现出线性递减的态势。依据电感元件的伏秒平衡原理,可以推导出涉及开关管占空比、电感元件电感量、输入电压以及输出电压之间关系的数学公式,这些公式对于深入理解和设计BUCK变换器具有关键性的指导意义。 接下来,文章对CCM和DCM两种模式进行了详细的比较分析。在CCM模式下,电感电流在整个开关周期内均保持连续的状态,而在DCM模式下,电感电流则会出现中断现象。确定BUCK变换器工作模式的关键依据是其电感电流纹波值与输出电流值相等这一边界条件。当电流纹波值等于零,即在整个开关周期内电感电流保持完全连续时,BUCK变换器被归类为CCM模式;相对地,若电流纹波值大于零,则表明变换器处于DCM模式;介于两者之间的情况则界定为CCM与DCM的过渡状态。 在DCM模式下,对BUCK...

80,489

社区成员

发帖
与我相关
我的任务
社区描述
移动平台 Android
androidandroid-studioandroidx 技术论坛(原bbs)
社区管理员
  • Android
  • yechaoa
  • 失落夏天
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧