这里展示如何使用 Garbage Collector for C and C++,只限于linux平台
DISCLAIMER: 这里的内容是我个人学习的体会, 你可以在你的任何程序中使用这里的技术.我不对使用这种方法造成的后果负责,我相信你可以正确的用你自己的方法编写程序.
使用GC的意义:
C语言的程序经常要动态的申请内存,如果申请到的内存没有用free()释放,只有到程序退出时才会由操作系统释放所申请的内存. 这对于很短暂运行的程序,比如ls命令,无论如何不是大问题. 但是我们写的一些internet服务程序可能会长期运行,那些没有释放的内存随时间的推移越来越多,结果程序就失败了.
GC功能就是程序中回收那些泄漏内存的功能,在java,lisp,python等语言都有,我们C/C++语言的爱好者不能让它们嘲笑我们没有这些功能吧,而且GC会使我们的程序更强壮.所以知道我们拥有这个工具还是挺不错的.
首先到 http://www.hpl.hp.com/personal/Hans_Boehm/gc/网站下载软件,包名字为 gc.tar.gz
然后安装:
cd ~ 进入自己的HOME目录
解包 tar xvzf gc.tar.gz 在~/gc6.1下解包, 假定版本是6.1,其它版本类似
编译 cd gc6.1
./configure
make
make check 如果这里显示 gc 不工作,你就不好运了.google一下其它的包吧.
用root身分安装:
su 输入root帐户密码
make install 默认的库安装在 /usr/local/lib目录下
下面更新库搜索路径
cd /etc
编辑 ld.so.conf, 结尾加一句 /usr/local/lib
运行 /sbin/ldconfig
exit 退出root帐户
好了, 下面看看我们怎么使用吧.
一. 把头文件放到自己方便的地方,或者每次包括 "~/gc6.1/include/gc.h"
二. 连接GC库: 动态的连接 gcc a.cpp -lgc -ldl 使用libgc.so, libdl.so两个库
静态的连接 gcc a.cpp /usr/local/lib/libgc.a -lpthread 使用libpthread.so
静态连接的好处是可以拷贝到类似的系统中用,比如另外一台标准安装的Redhat 8.0,而不用在那台机器上安装GC库.
一些示范的用法:
1. 把GC作为内存泄漏的检测工具, 方法如下:
#include "../gc6.1/include/leak_detector.h"
[code:1:d280d64dd4]
int main()
{
int *p[10];
int i;
GC_find_leak = 1; //如果去掉这一句,就变成了标准的GC功能,这一句使它按内存检测方式运行
for (i = 0; i < 10; ++i) {
p[i] = (int*)malloc(sizeof(int)+i);
}
for (i = 2; i < 10; ++i) {
free(p[i]);
}
for (i = 0; i < 9; ++i) {
p[i] = (int*)malloc(sizeof(int)+i);
}
CHECK_LEAKS(); //标准GC不需要这一句,这里强制GC_gcollect();
}
[/code:1:d280d64dd4]
编译运行如下:
gcc a.c -lgc -ldl 或者 gcc a.c libgc.a -lpthread
./a.out
显示:
Leaked composite object at 0x805bff0 (b.c:10, sz=5)
Leaked composite object at 0x805afe8 (b.c:10, sz=4)
当我们调试结束后,可以把检测去掉就可以了.
2.一个更有意义的做法是,我们使用标准GC的功能,那么我们根本不用释放申请的内存,不用时就忘掉它好了.
#include "../gc6.1/include/gc.h"
#define malloc(n) GC_malloc(n) //这样可以方便的使用而不改程序中原有的malloc
[code:1:d280d64dd4]
#include <stdio.h>
int main()
{
int i;
char *p;
for (i = 0; i < 10000; ++i) {
p = malloc(100000*sizeof(int)); //malloc许多次,没有free
if(p==0) {printf("No memory\n");exit(1);}
}
}
[/code:1:d280d64dd4]
编译 gcc b.c -lgc -ldl 或者 gcc b.c /usr/local/lib/libgc.a -lpthread
./a.out &
看看吧, 不会把内存用光的.不会显示No memory信息.
3. 在C++中也是可以使用的.
方法一: 替换调原来的malloc库函数:
在g++中, C++的new和delete是通过调用malloc实现内存分配的,我们可以直接替换掉malloc函数.
[code:1:d280d64dd4]
#include <iostream>
using namespace std;
#include <cstdlib>
#include "gc6.1/include/gc.h"
//override malloc library
void *malloc(size_t size) {
return GC_malloc(size);
}
void free(void* ptr)
{
return GC_free(ptr);
}
int main() {
while(1)
char *p = new char[10000];
return 0;
}