throw try...catch...内存泄漏问题
2013-07-20 12:00
169 查看
我编了一个服务器程序,多线程,在测试的时候没有发现内存泄漏,但是在实际应用中,发现较长一段时间后,程序占用了大量的虚拟内存。最近发现是在处理throw try catch异常事务时出现的,通过简单的编程测试可以证实throw try catch语句的内存泄漏问题,求教高手有什么好的解决方案?
测试例程如下:
对于throw try...catch...语句,存在内存泄漏问题:如果是使用堆栈内存,不存在内存泄漏问题,但如果是使用堆内存,就存在内存泄漏问题。
测试例程
#include <iostream.h>
#include <windows.h>
#include <string>
#include <malloc.h>
class AA
{
private:
char * buff;
public:
AA():buff(NULL){}
~AA()
{
if(buff!=NULL)
delete buff;
}
void Init(){buff = new char[10240];}
};
void test(void)
{ //会产生内存泄漏,因为aa.Init()中分配了堆内存,在throw时内存来不及释放。
AA aa;
aa.Init();
throw "test_error ";
return ;
}
void test2(void)
{ //不会产生内存泄漏,因为buff使用的是堆栈内存,在函数结束时清理堆栈将自动清理堆栈
char buff[10240];
throw "test_error2";
return ;
}
void test3(void)
{ //会产生内存泄漏,因为new中分配了堆内存,在throw时内存来不及释放。
char *buff;
buff = new char[10240];
throw "test_error2";
delete buff;
return;
}
void test4(void)
{ //会产生内存泄漏,因为aa=".."中分配了堆内存,在throw时内存来不及释放。(证明标准的C++类也存在同样的内存泄漏问题。)
std::string aa;
aa = "kasdfasdfasdfaksldfjas;lkasdjg;laksdjg;alskdjgf;alskdjf;alksjd;kgjas;dlkjfalskjdhlkasjghlaksdjhglaskdjgfashdkjlg";
throw "test_error ";
return ;
}
void test5(void)
{ //不会产生内存泄漏,因为_allca使用的是堆栈内存,在函数结束时清理堆栈将自动清理堆栈,所以该内存的有效使用范围只在本函数内,而且不能使用free释放内存。
char * buff;
buff = (char *)_alloca(1024);
throw "test_error5";
return ;
}
int main(void)
{
for(int i=0;i<10000;i++)
{
try{
test5();
}
catch(const char *ser)
{
}
cout << i << "\r";
Sleep(10);
}
return 0;
}
如果需求保证内存泄漏问题,需要管理内存链表,在catch事务处理中进行内存检查和回收。但是在多线程程序中比较难以处理。
如:
class bb
{
private:
MyMemoryList *p;
public:
bb(); --> p->Add(this); // 增加到管理链表
~bb(); --> p->Del(this); // 从链表中删除,如果碰到throw来不及删除,将在p中留下记录。
}
另一种方法是在碰到throw时,把因该清除的内存清理干净。这样做的难度比较大。
测试例程如下:
对于throw try...catch...语句,存在内存泄漏问题:如果是使用堆栈内存,不存在内存泄漏问题,但如果是使用堆内存,就存在内存泄漏问题。
测试例程
#include <iostream.h>
#include <windows.h>
#include <string>
#include <malloc.h>
class AA
{
private:
char * buff;
public:
AA():buff(NULL){}
~AA()
{
if(buff!=NULL)
delete buff;
}
void Init(){buff = new char[10240];}
};
void test(void)
{ //会产生内存泄漏,因为aa.Init()中分配了堆内存,在throw时内存来不及释放。
AA aa;
aa.Init();
throw "test_error ";
return ;
}
void test2(void)
{ //不会产生内存泄漏,因为buff使用的是堆栈内存,在函数结束时清理堆栈将自动清理堆栈
char buff[10240];
throw "test_error2";
return ;
}
void test3(void)
{ //会产生内存泄漏,因为new中分配了堆内存,在throw时内存来不及释放。
char *buff;
buff = new char[10240];
throw "test_error2";
delete buff;
return;
}
void test4(void)
{ //会产生内存泄漏,因为aa=".."中分配了堆内存,在throw时内存来不及释放。(证明标准的C++类也存在同样的内存泄漏问题。)
std::string aa;
aa = "kasdfasdfasdfaksldfjas;lkasdjg;laksdjg;alskdjgf;alskdjf;alksjd;kgjas;dlkjfalskjdhlkasjghlaksdjhglaskdjgfashdkjlg";
throw "test_error ";
return ;
}
void test5(void)
{ //不会产生内存泄漏,因为_allca使用的是堆栈内存,在函数结束时清理堆栈将自动清理堆栈,所以该内存的有效使用范围只在本函数内,而且不能使用free释放内存。
char * buff;
buff = (char *)_alloca(1024);
throw "test_error5";
return ;
}
int main(void)
{
for(int i=0;i<10000;i++)
{
try{
test5();
}
catch(const char *ser)
{
}
cout << i << "\r";
Sleep(10);
}
return 0;
}
如果需求保证内存泄漏问题,需要管理内存链表,在catch事务处理中进行内存检查和回收。但是在多线程程序中比较难以处理。
如:
class bb
{
private:
MyMemoryList *p;
public:
bb(); --> p->Add(this); // 增加到管理链表
~bb(); --> p->Del(this); // 从链表中删除,如果碰到throw来不及删除,将在p中留下记录。
}
另一种方法是在碰到throw时,把因该清除的内存清理干净。这样做的难度比较大。
相关文章推荐
- try throw catch 多个throw 捕获的问题
- 关于Java中try catch finally throw return的执行顺序问题
- c++ try catch 问题(没有throw就会被删除,加上/EHa这样就不会被删除)
- 在try,catch,finally中return,throw覆盖的问题总结
- Try throw catch 的一个问题
- JAVA语言如何进行异常处理,关键字:throws,throw,try,catch,finally分别代表什么意义?在try块中可以抛出异常吗?
- throw_try_catch
- try/catch、throws和throw
- c++ try catch 问题
- java异常处理之throw, throws,try和catch
- 关于throw try catch
- JavaScript Errors - Throw and Try to Catch
- JavaScript基础1:JavaScript 错误 - Throw、Try 和 Catch
- JavaScript 错误处理, Throw、Try 和 Catch入门
- 从JVM指令层面看try-catch-finally返回值问题
- try...catch...throw
- php框架中,try,catch不能用的问题(转载)
- try,catch,throw异常捕捉
- c++ try catch 问题 http://blog.csdn.net/windhaunting/article/details/4735338
- JAVA之旅(十)——异常的概述,Try-Catch,异常声明Throws,多异常处理,自定义异常,Throw和Throws的区别