当前位置:网络安全 > vs2010 调试时查看内存不足_Vs2010 崩溃(虚拟内存不足)

vs2010 调试时查看内存不足_Vs2010 崩溃(虚拟内存不足)

  • 发布:2023-09-23 10:57

VS2010提示内存不足问题。

简述:

MFC?对话框应用程序中在运行时提示“内存不足”,如下图:

查找原因,有的说是因为栈区或者堆区内存小导致的问题,建议设置编译器内存(网上一大堆内容)。

我的数据量并不是特别大,我分配了20M的栈空间之后问题还是如此,因此我怀疑出错的地方另有原因。

原因:

在我的程序中用到std::vector在其中有将vector中的内容erase掉的部分,

std::list::iterator iterSound = (*mainIter).mSoundList.begin();

for( ; iterSound!=(*mainIter).mSoundList.end(); iterSound++)

{

if(1==(*iterSound).flag)

{

(*mainIter).mSoundList.erase(iterSound); // 内存不足问题出现地方

}

else

{

(*iterSound).flag = 0;

}

//mCourseSoundList.DeleteString(A2W((*iterSound).mSound.getName().c_str()));

}

经过分析大致确定问题出在

(*mainIter).mSoundList.erase(iterSound);部分,

因为vector的erase方法的一个重载用法是删除某个元素,并把下一个元素返回。

由于该出erase掉了iterSound导致iterSound++的时候出现不可预知的问题,也就导致IterSound永远都不会与vector.end()相等。所以导致内存被耗尽。出现一些不可预知的错误。

解决方法:

std::list::iterator iterSound = (*mainIter).mSoundList.begin();

for( ; iterSound!=(*mainIter).mSoundList.end(); )

{

if(1==(*iterSound).flag)

{

iterSound = (*mainIter).mSoundList.erase(iterSound); // 解决内存不足

}

else

{

(*iterSound).flag = 0;

iterSound++;

? }

//mCourseSoundList.DeleteString(A2W((*iterSound).mSound.getName().c_str()));

}这样在erase之后把后一个元素的内容返回

到IterSound以便使该问题得到解决。

?

当 Visual Studio 崩溃并且虚拟内存不足时,会显示此消息。 但是,这并不意味着系统中的虚拟内存不足,而是 Visual Studio 将用尽地址空间。 此错误通常出现在具有 32 位操作系统的计算机上,这些操作系统会将 Visual Studio 的地址空间限制为 2GB。 在 64 位系统上,很少出现此错误。

当 Visual Studio 缓存大量数据或运行多个大量耗用内存的进程时,通常会发生此错误。

以下情况涉及缓存大量数据,通常只需重新启动 Visual Studio 即可解决。

安装后首次运行 Visual Studio。安装或卸载扩展。选择或自定义工具箱项。更改 Visual Studio 设置。允许系统在 Visual Studio 打开时进入睡眠(休眠)模式。

以下情况需要大量活动内存。 在这些情况下,建议运行 Visual Studio 时只打开基本组件,或在另一个 Visual Studio 实例中运行其他进程。

生成大型解决方案。从 2008 升级解决方案。对解决方案重定目标。在编辑代码时运行团队资源管理器。对多个项目运行 IntelliTrace。

如果这些措施不足以防止出现错误,则可通过遵循以下语法使用 bcedit.exe 来增加 Windows Vista、Windows 7 或 Windows Server 2008 系统上的可用地址空间:

bcdedit /set IncreaseUserVa 3072

这样可将 x86 系统中的用户模式虚拟内存分配从 2GB 增加至 3GB。

?

必须以管理员身份运行 bcdedit.exe。 如果您的系统已启用 BitLocker 加密,则必须先挂起 Bitlocker,然后进行更改,重新启动,并重新启用 Bitlocker。

?

以上是MSDN上的解释。可参考解决

内存泄漏定义

内存泄漏指的是在程序里动态申请的内存在使用完后,没有进行释放,导致这部分内存没有被系统回收,久而久之,可能导致程序内存不断增大,系统内存不足

内存泄漏危害

系统可用内存越来越小机器卡顿系统崩溃排查起来很困难

定位方法

内存泄漏方法有很多种,也可以借助第三方插件 Visual Leak Detector(开源,免费)进行排查,本篇文章介绍一种?借助Visual Studio 调试器和 C 运行时 (CRT) 库进行排查的方法。

1、我们以一个小demo进行分析:

#include "stdafx.h"

#include

using namespace std;

class CStudent

{

public:

CStudent(int age, std::string name) : m_age(age), m_name(name) {}

~CStudent() {}

int Age(){return m_age;}

private:

int m_age;

std::string m_name;

};

void MemoryTest()

{

CStudent* pStudent = new CStudent(20, "xiaoming");

int age = pStudent->Age();

}

int _tmain(int argc, _TCHAR* argv[])

{

MemoryTest();

return 0;

}

很容易可以发现在MemoryTest函数内第一行是有内存泄漏的,但此时编译器以及程序运行时不会报任何内存泄漏信息。

2、加入相关代码

#ifdef _DEBUG

#define new new(_NORMAL_BLOCK, __FILE__, __LINE__)

#endif

_CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) | _CRTDBG_LEAK_CHECK_DF);

#include "stdafx.h"

#include

#ifdef _DEBUG

#define new new(_NORMAL_BLOCK, __FILE__, __LINE__)

#endif

class CStudent

{

public:

CStudent(int age, std::string name) : m_age(age), m_name(name) {}

~CStudent() {}

int Age(){return m_age;}

private:

int m_age;

std::string m_name;

};

void MemoryTest()

{

CStudent* pStudent = new CStudent(20, "xiaoming");

int age = pStudent->Age();

}

int _tmain(int argc, _TCHAR* argv[])

{

_CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) | _CRTDBG_LEAK_CHECK_DF);

MemoryTest();

return 0;

}

此时输出信息会报内存泄漏

3、重新运行程序,在监听中加入{,,msvcr100d.dll}_crtBreakAlloc,值为211,程序会在内存泄漏的代码位置中断

4、点击中断,查看调用堆栈,即可看到内存泄漏代码位置

5、在相应位置释放资源即可

?

VS2015内存泄漏检测、追踪方法:

https://www.sychzs.cn/lihaidong1991/article/details/103486358

相关文章