Утечка памяти. Visual Leak Detector для Visual Studio 2008-2015

Утечка памяти достаточно серьезная проблема возникающая при работе программы. Масштабность проявляется особенно при длительной работе программы, когда программа может исчерпать лимит выделения для нее памяти, а это приведет к очень нехорошим последствиям.

До недавнего времени я сам не обращал внимания на утечки, однако перед выпуском SkyXEngine 0.9.0 решил полностью устранить. Эта затея заняла не одну неделю))

Определение

Утечка памяти (memory leak) — процесс уменьшения объема свободной оперативной памяти, вследствие работы программы, при которой программа выделяет память динамически, но не освобождает ее.

Последствия такого явления очевидны, все зависит от масштаба, если в ходе работы программы потерялось несколько килобайт то это несущественно, а вот если несколько сотен мегабайт … это уже другое дело.

Нюансы

Мной было опробован ручной способ описанный в этой статье. Однако он требует некоторых телодвижения, что не всегда удобно)) Когда в коде появились структуры/классы с выравниванием памяти, типа такого:

__declspec(align(16)) struct SMVECTOR
{
	union
	{
		__m128 mmv;
		struct
		{
			float x;
			float y;
			float z;
			float w;
		};
	};


	void* operator new(size_t size)
	{
		return (_aligned_malloc(size, 16));
	};
				
	void operator delete(void* ptr)
	{
		_aligned_free(ptr);
	};

	void* operator new[](size_t size)
	{
		return (_aligned_malloc(size, 16));
	};
				
	void operator delete[](void* ptr)
	{
		_aligned_free(ptr);
	};
};

Сразу возникли разного рода ошибки, то есть использование этого метода из статьи уже требовало еще дополнительного телодвижения, разбирать ошибки не было никакого желания.

Также можно самому сделать некое подобие сборщика мусора, но стоит учесть что это надо делать.

Visual Leak Detector (VLD)

Для обладателей visual studio 2008-2015 можно использовать Visual Leak Detector (VLD), сам использую в vs 2013. Очень удобный, простой и понятный инструмент. С выравниванием памяти нормально уживается. Однако всю информацию об утечках можно будет получить только по завершению работы программы в debug режиме.

Ссылка на visualstudio.com

Ссылка на codeplex.com (отсюда качал)

Использовать достаточно просто, надо скачать и установить.

Если Visual Studio установлена, то никаких действий по настройке совершать более не надо, если же Visual Studio будет устанавливаться после VLD то надо настроить пути до файлов VLD.

Чтобы начать использовать достаточно в начале подключить vld.h, то есть:

#include <vld.h>

И все!

По завершении работы программы, если есть утечки, в окно output будут выведены сообщения вида:

WARNING: Visual Leak Detector detected memory leaks!
---------- Block 2421 at 0x0057AD10: 24 bytes ----------
  Leak Hash: 0x8FFD0DFE, Count: 1, Total 24 bytes
  Call Stack (TID 4920):
    ntdll.dll!RtlAllocateHeap()
    f:\dd\vctools\crt\crtw32\heap\new.cpp (59): Script4Game_d.exe!operator new() + 0x9 bytes
    d:\project\s4g\src\s4g\s4g_parser.cpp (2616): Script4Game_d.exe!s4g_Parser::matchID() + 0x7 bytes
    d:\project\s4g\src\s4g\s4g_parser.cpp (46): Script4Game_d.exe!s4g_Parser::parse()
    d:\project\s4g\src\s4g\s4g.cpp (100): Script4Game_d.exe!s4g_LoadCode() + 0x11 bytes
    d:\project\s4g\src\s4g\script4game.cpp (111): Script4Game_d.exe!WinMain() + 0x12 bytes
    f:\dd\vctools\crt\crtw32\startup\crt0.c (165): Script4Game_d.exe!WinMainCRTStartup()
    kernel32.dll!BaseThreadInitThunk() + 0x12 bytes
    ntdll.dll!RtlInitializeExceptionChain() + 0x63 bytes
    ntdll.dll!RtlInitializeExceptionChain() + 0x36 bytes
  Data:
    44 56 B1 00    07 00 00 00    8C A6 52 00    00 00 00 00     DV...... ..R.....
    00 00 00 00    00 00 00 00                                   ........ ........


---------- Block 2422 at 0x0057B370: 24 bytes ----------
  Leak Hash: 0x1F8141B9, Count: 1, Total 24 bytes
  Call Stack (TID 4920):
    ntdll.dll!RtlAllocateHeap()
    f:\dd\vctools\crt\crtw32\heap\new.cpp (59): Script4Game_d.exe!operator new() + 0x9 bytes
    d:\project\s4g\src\s4g\s4g_parser.cpp (2627): Script4Game_d.exe!s4g_Parser::matchRVal() + 0x7 bytes
    d:\project\s4g\src\s4g\s4g_parser.cpp (34): Script4Game_d.exe!s4g_Parser::parse() + 0x17 bytes
    d:\project\s4g\src\s4g\s4g.cpp (100): Script4Game_d.exe!s4g_LoadCode() + 0x11 bytes
    d:\project\s4g\src\s4g\script4game.cpp (111): Script4Game_d.exe!WinMain() + 0x12 bytes
    f:\dd\vctools\crt\crtw32\startup\crt0.c (165): Script4Game_d.exe!WinMainCRTStartup()
    kernel32.dll!BaseThreadInitThunk() + 0x12 bytes
    ntdll.dll!RtlInitializeExceptionChain() + 0x63 bytes
    ntdll.dll!RtlInitializeExceptionChain() + 0x36 bytes
  Data:
    DC 55 B1 00    19 00 00 00    BC A6 52 00    00 00 00 00     .U...... ..R.....
    00 00 00 00    00 00 00 00                                   ........ ........

По первому сообщению, утечка памяти произошла вот здесь: d:\project\s4g\src\s4g\s4g_parser.cpp (2616): а именно s4g_Parser::matchID():

s4g_ConstNode * pNode = new s4g_ConstNode(tmp->m_pLex);

Как видно, все указывается вплоть до строки на которой произошло выделение не освобожденной памяти.

VLD достаточно хороший инструмент для поиска утечек памяти. Однако как с ним обстоят дела вне Visual Studio мне не известно))

Поделиться:

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

*

*

code