}
最终,Chrome将所有的内存分配与释放集中到这2个函数,其中过滤了自己内部的一些
内存操作,否则可能带来死循环而导致程序崩溃:
void MemoryHook::OnTrack(HANDLE heap, int32 id, int32 size) {
// Don't notify about allocations to our internal heap.
if (heap == heap_)
return;
if (watcher_)
watcher_->OnTrack(heap, id, size);
}
void MemoryHook::OnUntrack(HANDLE heap, int32 id, int32 size) {
// Don't notify about allocations to our internal heap.
if (heap == heap_)
return;
if (watcher_)
watcher_->OnUntrack(heap, id, size);
}
现在我们来看看Chrome中记录数据的类StatsCounter,同时StatsCounter是使用共享内
存的方式来获得数据内存:
int* StatsCounter::GetPtr() {
StatsTable* table = StatsTable::current();
if (!table)
return NULL;
// If counter_id_ is -1, then we haven't looked it up yet.
if (counter_id_ == -1) {
counter_id_ = table->FindCounter(name_);
if (table->GetSlot() == 0) {
if (!table->RegisterThread("")) {
// There is no room for this thread. This thread
// cannot use counters.
counter_id_ = 0;
return NULL;
}
}
}
// If counter_id_ is > 0, then we have a valid counter.
if (counter_id_ > 0)
return table->GetLocation(counter_id_, table->GetSlot());
// counter_id_ was zero, which means the table is full.
return NULL;
}
我们自己的程序中并不需要这种共享内存的方式来获得内存,因此,笔者去掉了从共享
内存获取内存地址指针的方式,直接使用变量:
int* StatsCounter::GetPtr() {
//We don't use Share Memory in our single process.
return &ptr_data_;
}
这样做可以大大简化我们的代码,同时,我们如果稍加修改 StatsCounter 类,我们还
可以获得不同线程占用的内存量,并且实时监控。
接下来我们便可以开始移植代码了,在对原来代码一些小小的修改上,我们去掉了许多
我们不需要的代码,同时为了方便测试,创建了一个监视窗口,每秒刷新一次,在控制台中
操作内存分配与释放:
int _tmain(int argc, _TCHAR* argv[])
{
CreateMemoryWatcher();
CreateBackgroundThread();
CreateBackgroundFrm();
g_memory_watcher->SetLogName("memwatcher");
//g_memory_watcher->DumpLeaks();
char szData[128];
void *p = NULL;
while (true)
{
std::cin.getline(szData, 128);
if (strcmp(szData, "exit") == 0)
break;
else if (strcmp(szData, "free") == 0)
free(p);
else if (strcmp(szData, "dump") == 0)
SetEvent(g_dump_event);
else
{
int size = atoi(szData);
if (size > 0)
p = malloc(size);
}
}
DeleteMemoryWatcher();
StopBackgroundThread();
CloseBackgroundFrm();
std::cout << std::endl;
return 0;
方便的内存使用记录查看可以使我们的程序更具有专业性和实用性,在很大的程度上可
以方便用户对程序的操作和管理等。我们同样也可以使用这种方法来给我们的程序添加一个
内存查看工具。由于有详细的内存分配和释放记录,这样不仅方便了用户,同时还可以给我
们开发者解决一些内存泄漏问题和调试程序带来了很多方便之处。希望读者们看完本文后能
够有一些启发,更多新的创意和愉快的一天。
|