我的软件在大量分配后仍然使用一些内存
My software is still using some memory after lots of allocations
我在Windows上用c++写了一个小的队列类。
只是为了测试,我分配了1,000,000个int
并读取它们。
队列正在正确地完成它的工作,并且非常快,但问题是在完成释放后,任务管理器报告了一些内存使用情况。例如,我仍然得到2MB的内存,尽管所有这些整数导致400MB以上的内存。
我认为这是由于操作系统没有执行某种GC或其他原因,但是现在我发现当我分配100,000,000个整数(之前的数字的10倍)时,这个值(2MB)变成了13MB。我找不到漏洞。
下面是代码;如您所见,我释放了所有内容:
#pragma once
#include <exception>
template <class T>
class colist_item
{
public:
colist_item() { }
~colist_item() { }
T value;
colist_item *next;
};
template <class T>
class colist
{
public:
colist() { this->m_root = NULL; this->m_count = 0; }
~colist() { }
void enqueue(T value);
T dequeue();
T *peek();
int count();
private:
colist_item<T> *m_root;
int m_count;
};
template <class T>
void colist<T>::enqueue(T value)
{
if (this->m_root == NULL) {
this->m_root = new colist_item<T>();
this->m_root->value = value;
this->m_root->next = NULL;
} else {
colist_item<T> *tempitem = new colist_item<T>();
tempitem->value = value;
tempitem->next = this->m_root;
this->m_root = tempitem;
}
this->m_count++;
}
template <class T>
T colist<T>::dequeue()
{
if (this->m_root == NULL) {
throw std::exception();
} else {
T retval = this->m_root->value;
colist_item<T> *next = this->m_root->next;
delete this->m_root;
this->m_root = next;
this->m_count--;
return retval;
}
}
template <class T>
T *colist<T>::peek()
{
if (this->m_root == NULL) {
return NULL;
} else {
T retval = this->m_root->value;
return &retval;
}
}
template <class T>
int colist<T>::count()
{
return this->m_count;
}
主:#include <iostream>
#include <limits>
#include "colist.h"
#include <time.h>
const int kNumItems = 100000000;
using namespace std;
void puttest(colist<int> *list)
{
for(int i = 0; i < kNumItems; i++)
list->enqueue(i);
}
void readtest(colist<int> *list)
{
for(int i = 0; i < kNumItems; i++)
list->dequeue();
}
int main(int argc, char *argv[])
{
colist<int> list;
cout << "Testing with : " << kNumItems << " elements" << endl;
clock_t start = clock();
puttest(&list);
clock_t end = clock();
double ms = ((end - start));
cout << "puttest: " << ms << endl;
start = clock();
readtest(&list);
end = clock();
ms = ((end - start));
cout << "readtest: " << ms << endl;
cin.ignore(std::numeric_limits<std::streamsize>::max(), 'n');
}
有几个bug
没有析构函数。
您没有泄漏任何内存,因为您删除了所有项。但是,如果您没有手动删除它们,那么您的类在超出作用域时就会泄漏。添加一个析构函数,只删除列表中的所有项。
Dequeue不是异常安全:
T retval = this->m_root->value;
colist_item<T> *next = this->m_root->next;
delete this->m_root; // If T is badly designed it could potentially throw an exception.
this->m_root = next; // Now you have m_root pointing at a bad object. The idea is to
// make sure an exception can not damage your internal structure
// of your object. Thus remove it from the chain before you call
// delete.
// Like this
T retval = m_root.value;
colist_item<T>* oldhead = m_root;
m_root = oldhead->next;
// Internal structure updated.
// Safe to do dangerous tasks.
delete oldhead;
在构造
时使用初始化列表colist() { this->m_root = NULL; this->m_count = 0; }
// should be
colist(): m_root(NULL), m_count(0) {}
你不需要到处使用this
。
我知道它在java中是被鼓励的,但在c++中通常不被鼓励,但被认为是一种风格。
运行http://valgrind.org/以确保没有内存泄漏。
我如何告诉操作系统我已经完成了分配,它可以释放未使用的内存?
当你请求更多内存时,c++库将重用操作系统提供的内存。所以,一般来说,这不是问题。
有时候,由于内存碎片,一些内存块真的很难回收。在这种情况下,您可能需要使用Arena分配器。
正如在注释中提到的,您不应该依赖任务管理器来分析程序的内存使用情况。这个问题列出了几个适合于内存泄漏检测的Windows工具。
相关文章:
- 将字符串存储在c++中的稳定内存中
- C++ 指针的内存地址和指向数组的内存地址如何相同?
- Win32编译器选项和内存分配
- 当vector是tje全局变量时,c++中vector的内存管理
- 带内存和隔离功能的SQLite
- 是否可以通过C++扩展强制多个python进程共享同一内存
- 迭代时从向量和内存中删除对象
- 在C++中打印指向不同基元数据类型的指针的内存地址
- 这个指针和内存代码打印是什么?我不知道是打印垃圾还是如何打印我需要的值
- 多个文件的内存分配错误"在抛出 'std :: bad_alloc' what (): std :: bad_alloc 的实例后终止调用" [C++]
- 为什么示例代码访问IUnknown中已删除的内存
- 在 C/C++ 中,是否可以通过使用指针更改"important"内存地址的值来创建简单的恶意软件?
- 列出当前过程并使用未记录的当前功能编写内存的软件技巧
- 大规模时间敏感软件的内存分析
- 乐观读取并使用 C/C++锁定 STM(软件事务内存)
- 内存映射一个巨大的文件在32位软件运行在64位操作系统
- 如何检测内存泄漏在我的Qt软件的Valgrind或其他工具
- 我的软件在大量分配后仍然使用一些内存
- 内存管理与c++插件插入到C软件
- 对软件事务内存友好的通用组件