TBOX的内存管理模型,参考了linux kernel的内存管理机制,并在其基础上做了一些改进和优化。
内存整体架构
large_pool
整个内存分配的最底层,都是基于large_pool的大块内存分配池,类似于linux的基于page的分配管理,不过有所不同的是,large_pool并没有像linux那样使用buddy算法进行(2^N)*page进行分配,这样如果需要2.1m的内存,需要分配4m的内存块,这样力度太大,非常浪费。
因此large_pool内部采用N*page的基于page_size为最小粒度进行分配,因此每次分配顶多浪费不到一页的空间。
而且如果需要的内存不到整页,剩下的内存也会一并返回给上层,如果
继续阅读 »
tbox的默认内存分配,是完全基于自己的内存池架构,支持内存的快速分配,和对碎片的优化,并且支持各种内存泄露、溢出检测。
如果不想用tbox内置的默认内存分配管理,也可以灵活切换到其他分配模式,因为tbox现在已经完全支持allocator架构,
只要在init阶段传入不同的分配器模型,就能快速切换分配模式,例如:
```c
/* 采用默认的tbox内存管理,启用内存池维护、碎片优化、内存泄露溢出检测等所有特性
* 相当于使用了:tb_default_allocator(tb_null, 0)
*/
tb_init(tb_null, tb_null);
/* 采用默认的tbox内存管理,启用
继续阅读 »
本文简单介绍c开发中的内存泄漏和动态内存分配函数,并使用valgrind分析c程序的内存泄漏问题。
1 什么是内存泄漏
c语言中,需由开发者负责内存的申请和释放,内存泄漏是指开发者在程序中使用动态内存分配函数xxlloc在堆(heap)上申请内存,内存在使用完毕后未使用free函数释放,那么这块内存在程序退出前都不能再次使用,导致内存使用逐渐增大,直至耗尽,程序异常退出。
继续阅读 »
在过去,内存泄漏并没有为 Web 开发人员带来巨大的问题。页面保持着相对简单,并且在页面之间的跳转时可以释放内存资源,即便还存在内存泄露,那也是小到可以被忽略。
现在,新的 Web 应用达到更高的水准,页面可能运行数小时而不跳转,通过 Web 服务动态检索和更新页面。JavaScript 语言特性也被发挥到极致,通过复杂的事件绑定、面向对象和闭包等特性构成了整个 Web 应用。面对这些变化,内存泄露问题变得越来越突出,尤其是之前那些通过刷新(导航)隐藏的内存泄露问题。
庆幸的是,如果你知道如何排查问题,内存泄露可以很轻易地被清除。即便是面对一些最麻烦的问题,如果你知道解决方案,也只需要少量的工作。虽然页面仍可能存在一些小的内存泄
继续阅读 »
本文简单介绍如何通过valgrind检测c语言中的非法读写内存,避免发生不可预测行为。
1 什么非法读写内存
1.1 非法写内存
非法写内存是指往不属于程序分配的内存中写入数据。比如malloc一段内存,大小只有5个字节,那么你只能往这5个字节空间写入数据(如果是拷贝字符串,只能写4个字节),在这5字节的内存空间之外写入数据,都是非法的。比如写数组时越界,拷贝字符串时忘记结尾结束符。
继续阅读 »
TBOX的内存分配在调试模式下,可以检测支持内存泄露和越界,而且还能精确定位到出问题的那块内存具体分配位置,和函数调用堆栈。
内存泄露检测
内存泄露的检测必须在程序退出的前一刻,调用tb_exit()的时候,才会执行,如果有泄露,会有详细输出到终端上。
c
tb_void_t tb_demo_leak()
{
tb_pointer_t data = tb_malloc0(10);
}
输出:
[tbox]: [error]: leak: 0x7f9d5b058908 at tb_static_fixed_pool_dump(): 735, memory/impl/stat
继续阅读 »
2.6.16后的内核, 对于查看进程内存使用分布, 更方便了. 在/proc/{pid} 路径下有一个smaps文件, 记录了进程内存使用情况, 在老的内核系统上, 这个文件是maps或memap , 而且老的内核下maps或memap文件记录的数据真不是人读的.
继续阅读 »
堆栈
栈用于静态内存分配,堆用于动态内存分配,它们都存储在内存RAM里。
栈
栈上面的变量一般编译时就分配好了(如函数临时变量等)。栈遵循LIFO(后进先出),非常方便管理。
栈的内存分配一般由系统管理,开发者无需关心。
读取栈上的变量速度很快。
当一个方法function被调用时,它会被push进栈中,该方法中的参数和局部变量存储在栈中,当方法执行完后,该方法pop出来,相应的栈空间被释放。
堆
堆上的变量,一般在程序运行期分配。
读取堆上数据速度较慢。
堆上的元素能够在任何时候被读取,开发者也能够在任何时候申请堆内存空间并且释放申请的空间,所以管理堆上的变量比较复杂。
通常我们说的内存管理实际上是指堆内存管理。
堆的大小
继续阅读 »
在QtWebkit的QWebView加载网页的时候,会随着每加载一次网页内存就会增加。为解决这个问题可以通过以下代码解决。
c++
QWebSettings::globalSettings()->setAttribute(QWebSettings::AutoLoadImages, false);
QWebSettings::globalSettings()->setMaximumPagesInCache(0);
QWebSettings::globalSettings()->setObjectCacheCapacities(0, 0, 0);
QWebSettings::globalSettings()->setOfflineS
继续阅读 »
mdtoc start
表现
解决方法
定位问题过程
gdb-python: 搞清楚python程序在做什么
准备gdb
接入gdb
查看线程
查看调用栈
coredump
其他命令
pyrasite: 连接进入python程序
psutil 查看python进程状态
guppy 取得内存使用的各种对象占用情况
无法回收的对象
不可回收对象的例子 🌰
objgraph 查找循环引用
继续阅读 »