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后未释放造成的.具体流程不详说.可以自己跟踪调试.
...全文
493 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的代码
内容概要:本文研究了基于角蜥蜴优化算法(HLOA)优化BP神经网络的风电功率预测模型,并提供了完整的Matlab代码实现。该方法通过引入HLOA算法对BP神经网络的初始权值和阈值进行全局寻优,有效解决了传统BP神经网络收敛速度慢、易陷入局部最优的问题,显著提升了风电功率预测的精度与鲁棒性。文中系统阐述了HLOA算法的生物启发机制、数学模型及其寻优过程,详细构建了HLOA-BP预测模型的技术框架,并结合实际风电场历史数据开展仿真实验。结果表明,该模型在均方根误差(RMSE)、平均绝对误差(MAE)和决定系数(R²)等关键指标上均优于标准BP神经网络及其他主流智能优化算法(如PSO、GWO)优化的对比模型,验证了其在短期风电功率预测中的优越性能。; 适合人群:具备一定机器学习与智能优化算法基础,从事新能源发电预测、电力系统调度、智能算法应用或相关领域研究的科研人员及工程技术人员,尤其适合电气工程、自动化、计算机等相关专业的研究生及以上学历层次的学习者与开发者。; 使用场景及目标:①应用于风电场短期功率预测,提升电网调度的稳定性与经济性;②为智能优化算法与神经网络融合的技术方案提供实践参考;③作为科研论文复现、算法改进或毕业课题设计的高质量模板。; 阅读建议:建议读者结合所提供的Matlab代码,按照文中模型构建流程逐步调试与运行,重点关注HLOA算法的参数敏感性分析及其对网络训练过程的影响,同时可尝试将该方法迁移至光伏发电预测、负荷预测或其他时间序列预测场景中进行拓展验证与性能对比。
内容概要:本文围绕“参与调峰的储能系统配置方案及经济性分析”展开研究,基于Matlab代码实现,重点探讨了储能系统在电力系统调峰中的优化配置方法与经济效益评估。研究内容涵盖储能系统应对负荷峰谷差、提升电网稳定性的技术路径,构建了综合考虑投资成本、运行维护费用、峰谷电价套利及电网服务收益的经济性模型,并通过仿真验证不同配置方案的技术可行性与经济优势。文中结合实际电力市场环境,系统分析了储能容量、功率配置、充放电策略等关键因素对经济性的影响,深入探讨了多场景下的敏感性变化规律,为储能项目的科学规划与投资决策提供了量化依据与理论支撑; 适合人群:具备电力系统基础知识和Matlab编程能力,从事新能源、储能技术、电力市场或相关领域研究的研发人员、工程技术人员及高校研究生。; 使用场景及目标:①用于科研复现EI期刊论文中的储能配置与经济性分析模型;②指导实际储能项目在调峰场景下的容量规划、运行策略制定与经济评估;③辅助高校教学与课题研究,深入理解储能系统在电力系统中的多重价值实现机制与优化逻辑。; 阅读建议:建议结合文中的Matlab代码与理论模型同步阅读,重点关注目标函数构建、约束条件设定及参数敏感性分析部分,通过调整输入数据和关键参数进行仿真验证,以深化对储能系统经济性影响因素及其优化路径的理解。
内容概要:本文围绕《【Koopman】遍历论、动态模态分解和库普曼算子谱特性的计算研究(Matlab代码实现)》展开,系统阐述了Koopman算子理论在非线性动力系统分析中的核心地位与应用价值,深入探讨了遍历论的基本概念、动态模态分解(DMD)算法的数学原理及其与Koopman算子谱分析之间的内在关联,重点剖析了如何通过有限数据逼近无限维Koopman算子的谱特性,并配套提供了完整的Matlab数值实现代码,帮助读者从理论推导与编程实践双重角度掌握这一先进的数据驱动建模方法。文中强调通过算法复现与实例分析,理解复杂动力系统的模态分解、稳定性判据及长期演化行为预测技术。; 适合人群:具备扎实的线性代数、微分方程和数值分析基础,对非线性动力系统、流体力学、信号处理或数据驱动建模范畴感兴趣,从事相关领域研究的研究生、高校科研人员及工程技术开发者。; 使用场景及目标:① 深入理解并实现Koopman算子理论及其在高维复杂系统中的谱分析方法;② 掌握动态模态分解(DMD)及其变体算法的核心流程,并应用于流场分析、气候模式识别、生物振荡等实际场景;③ 利用Matlab进行非线性系统关键模态的提取、重构与未来状态预测,提升对系统内在动力学机制的洞察力。; 阅读建议:建议读者在学习过程中紧密结合文中的Matlab代码进行逐行调试与修改,通过可视化结果反哺理论理解,同时推荐延伸阅读Koopman模式分解(KMD)、EDMD(Extended DMD)等先进方法,以拓宽在实际科研与工程问题中的应用视野。

80,490

社区成员

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

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