vfxmemory怎么android 查看内存泄露露

LeakCanary:检测所有的内存泄露
java.lang.OutOfMemoryError
at android.graphics.Bitmap.nativeCreate(Bitmap.java:-2)
at android.graphics.Bitmap.createBitmap(Bitmap.java:689)
at com.squareup.ui.SignView.createSignatureBitmap(SignView.java:121)
没有人喜欢OutOfMemory崩溃
在Square的注册界面,我们使用bitmap缓存绘制客户的签名,使用的bitmap大小等同于屏幕大小,当创建它时,我们有了大量的OOM崩溃。
我们尝试了一些方法,但是没有一个可以解决问题:使用Bitmap.Config.ALPHA_8(签名不需要颜色)。捕获OutOfMemoryError,触发GC并多次重试(灵感来源于GCUtils)。我们没有想过从Java 堆分配位图,幸运的是,Fresco 也没有。(注:Fresco是Facebook用于图片缓存的开源库,可以关注一些)
我们曾看错了方向
bitmap的大小并不是问题,当内存将要用完的时候,OOM可以随处发生。它们更多的发生在你创建一个像Bitmap这种比较大的对象的情况下。OOM只是一个症状源自于更深层次的问题:内存泄露。
什么是内存溢出?
某些对象生命周期有限,当它们的工作完成以后,将会被回收。如果一个对象在其生命周期结束以后仍被内存中引用,将会导致内存泄露。当泄露积累过多,该应用将耗尽内存。
比如,在Activity.OnDestroy()方法被调用以后,这个activity的各种层级视图和它们关联的位图都应该被回收掉,如果一个后台运行的线程有该activity的引用,activity相对应的内存将不能被回收,这最终会导致OutOfMemoryError崩溃。
追踪内存溢出
追踪内存溢出是一个手动过程, Raizlabs 的 Wrangling Dalvik 对此有很好的描述。
下面是关键步骤:
通过 Bugsnag, Crashlytics,或者 Developer Console 了解内存溢出。
尝试重现该问题。你可能需要通过购买或者借用遇到崩溃问题的特定设备。(并非所有设备都会呈现这些泄漏) !你还需要弄清楚是哪一系列操作触发泄漏,有可能是蛮力。
当泄露发送时,记录堆栈内容(点击此处获取代码)
使用MAT 或者YourKit 查看堆栈内容,并从中找出应该被回收的对象。
计算最短到 GC 根从该对象的强引用路径。
找出哪个引用路径不应该存在,并修复内存溢出问题。
该库会在你遇到OOM的时候完成以上全部操作,这样你就可以专注于解决内存溢出问题了。
LeakCanary简介
LeakCanary是一个可以在你调试的时候检测内存泄露的Java开源库。
让我们看一个小例子:
class Cat {
class Box {
Cat hiddenC
class Docker {
Box box = new Box();
Cat schrodingerCat = new Cat();
box.hiddenCat = schrodingerC
Docker.container =
创建一个RefWatcher实例并设计一个监听对象
// We expect schrodingerCat to be gone soon (or not), let's watch it.
refWatcher.watch(schrodingerCat);
当检测到泄漏时,您自动获得不错的泄漏痕迹:
* GC ROOT static Docker.container
* references Box.hiddenCat
* leaks Cat instance
我们知道你忙着写功能,所以我们很容易设置。只是一个代码行,LeakCanary 将会自动检测活动泄漏:
public class ExampleApplication extends Application {
@Override public void onCreate() {
super.onCreate();
LeakCanary.install(this);
你会得到一个Notification和一个很好的展示界面:
在使用LeakCanary以后,我们在自己的应用中发现了许多内存泄露问题,我们甚至发现了一些Android SDK的内存泄露。
结果是令人惊讶的,我们的OOM错误减少了94%。
如果你想消灭OOM错误,现在就使用 LeakCanary 吧!
本文原创地址:http://blog.csdn.net/lilu_leo/article/details/ 转载请声明。
2015年,开始尝试玩一下微信公众账号:
(window.slotbydup=window.slotbydup || []).push({
id: '2467140',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467141',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467143',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467148',
container: s,
size: '1000,90',
display: 'inlay-fix'LeakCanary:检测所有的内存泄露
java lang OutOfMemoryError
at android graphics Bitmap nativeCreate(Bitmap java:-2)
at android graphics Bitmap createBitmap(Bitmap java:689)
java.lang.OutOfMemoryError
at android.graphics.Bitmap.nativeCreate(Bitmap.java:-2)
at android.graphics.Bitmap.createBitmap(Bitmap.java:689)
at com.squareup.ui.SignView.createSignatureBitmap(SignView.java:121)
没有人喜欢OutOfMemory崩溃
在Square的注册界面,我们使用bitmap缓存绘制客户的签名,使用的bitmap大小等同于屏幕大小,当创建它时,我们有了大量的OOM崩溃。
我们尝试了一些方法,但是没有一个可以解决问题:使用Bitmap.Config.ALPHA_8(签名不需要颜色)。捕获OutOfMemoryError,触发GC并多次重试(灵感来源于GCUtils)。我们没有想过从Java 堆分配位图,幸运的是,Fresco 也没有。(注:Fresco是Facebook用于图片缓存的开源库,可以关注一些)
我们曾看错了方向
bitmap的大小并不是问题,当内存将要用完的时候,OOM可以随处发生。它们更多的发生在你创建一个像Bitmap这种比较大的对象的情况下。OOM只是一个症状源自于更深层次的问题:内存泄露。
什么是内存溢出?
某些对象生命周期有限,当它们的工作完成以后,将会被回收。如果一个对象在其生命周期结束以后仍被内存中引用,将会导致内存泄露。当泄露积累过多,该应用将耗尽内存。
比如,在Activity.OnDestroy()方法被调用以后,这个activity的各种层级视图和它们关联的位图都应该被回收掉,如果一个后台运行的线程有该activity的引用,activity相对应的内存将不能被回收,这最终会导致OutOfMemoryError崩溃。
追踪内存溢出
追踪内存溢出是一个手动过程, Raizlabs 的 Wrangling Dalvik 对此有很好的描述。
下面是关键步骤:
通过 Bugsnag, Crashlytics,或者 Developer Console 了解内存溢出。
尝试重现该问题。你可能需要通过购买或者借用遇到崩溃问题的特定设备。(并非所有设备都会呈现这些泄漏) !你还需要弄清楚是哪一系列操作触发泄漏,有可能是蛮力。
当泄露发送时,记录堆栈内容(点击此处获取代码)
使用MAT 或者YourKit 查看堆栈内容,并从中找出应该被回收的对象。
计算最短到 GC 根从该对象的强引用路径。
找出哪个引用路径不应该存在,并修复内存溢出问题。
该库会在你遇到OOM的时候完成以上全部操作,这样你就可以专注于解决内存溢出问题了。
LeakCanary简介
LeakCanary是一个可以在你调试的时候检测内存泄露的Java开源库。
让我们看一个小例子:
class Cat {
class Box {
Cat hiddenC
class Docker {
Box box = new Box();
Cat schrodingerCat = new Cat();
box.hiddenCat = schrodingerC
Docker.container =
创建一个RefWatcher实例并设计一个监听对象
// We expect schrodingerCat to be gone soon (or not), let's watch it.
refWatcher.watch(schrodingerCat);
当检测到泄漏时,您自动获得不错的泄漏痕迹:
* GC ROOT static Docker.container
* references Box.hiddenCat
* leaks Cat instance
我们知道你忙着写功能,所以我们很容易设置。只是一个代码行,LeakCanary 将会自动检测活动泄漏:
public class ExampleApplication extends Application {
@Override public void onCreate() {
super.onCreate();
LeakCanary.install(this);
你会得到一个Notification和一个很好的展示界面:
在使用LeakCanary以后,我们在自己的应用中发现了许多内存泄露问题,我们甚至发现了一些Android SDK的内存泄露。
结果是令人惊讶的,我们的OOM错误减少了94%。
如果你想消灭OOM错误,现在就使用 LeakCanary 吧!
本文原创地址:http://blog.csdn.net/lilu_leo/article/details/ 转载请声明。
2015年,开始尝试玩一下微信公众账号:内存调试&定位内存泄露的具体位置
//经常有分配内存但忘记释放的问题,项目小还好,项目一大就非常难找了
//找了好久从网上找到了 兰征鹏 大哥(大师?前辈?)的一个神作
//用起来十分方便,如下:
#include "vfxdebug.h"
#include "vfxmemory.h"
#define new VNEW
//注:第三步必须出现在每一个要用到new的.cpp文件中,在stdafx.h中包含会出现一堆错误
//关闭程序后,在输出中找,如果有内存泄露的话会找到类似的语句:&\meshes.cpp(65) :
Memory leak! There //have 8 bytes memory had not be delete. Alloc
ID : 0,双击便可直接定位
//-------------------------------&vfxdebug.h-------------------------------------
// VictoryCore Code
// debuging and memory manager
// Author : lanzhengpeng(兰征鹏)
// More author :
// Create time :
// Modify time :
//-----------------------------------------------------------------------------
#ifndef __VFX_DEBUG_H__
#define __VFX_DEBUG_H__
#pragma once
# define vT(x) x
#ifndef _DBG_WIDE
# if __CPL_FULL_VER &
# define __DBG_WIDE(_String) _String
# define __DBG_WIDE(_String) L##_String
# define _DBG_WIDE(String) __DBG_WIDE(String)
#ifndef _MFC
# ifndef ASSERT
# include &cassert&
# define ASSERT assert
# if _DEBUG
# if !defined(THIS_FILE)
# define THIS_FILE __FILE__
# if !defined(TRACE)
# define TRACE _vfxTrace
# if !defined(VERIFY)
# define VERIFY(f) ASSERT(f)
# if !defined(ASSERT_VALID)
# define ASSERT_VALID(p)
_vfxAssertValid(p,_DBG_WIDE(__FILE__),__LINE__)
# if !defined(ASSERT_THIS)
# define ASSERT_THIS(p)
_vfxAssertThis(p,_DBG_WIDE(__FILE__),__LINE__)
# if !defined(TRACE0)
# define TRACE0(sz) & &
& &_vfxTrace(sz)
# if !defined(TRACE1)
# define TRACE1(sz, p1) & &
&_vfxTrace(sz, p1)
# if !defined(TRACE2)
# define TRACE2(sz, p1, p2) & &
&_vfxTrace(sz, p1, p2)
# if !defined(TRACE3)
# define TRACE3(sz, p1, p2, p3) &_vfxTrace(sz, p1,
# else & // _DEBUG
# if !defined(VERIFY)
# define VERIFY(f) ((void)(f))
# if !defined(ASSERT_VALID)
# define ASSERT_VALID(pOb) ((void)0)
# if !defined(ASSERT_THIS)
# define ASSERT_THISD(p) ((void)0)
# if !defined(TRACE)
# define TRACE _vfxTrace
# if !defined(TRACE0)
# define TRACE0(sz)
# if !defined(TRACE1)
# define TRACE1(sz, p1)
# if !defined(TRACE2)
# define TRACE2(sz, p1, p2)
# if !defined(TRACE3)
# define TRACE3(sz, p1, p2, p3)
# endif // !_DEBUG
# if !defined(UNUSED)
# define UNUSED(x)
#endif //end _MFC
# ifndef _NOVNEW
# define _vfx_New _vfxMemoryNew
# define _vfx_Delete _vfxMemoryDelete
# include &new&
# undef new
# if _DEBUG
# define VFX_DEBUG_MEMORY 1
# undef VFX_DEBUG_MEMORY
//# define VFX_DEBUG_MEMORY 1
void * _vfx_New(size_t nSize,const char * file,unsigned int
void _vfx_Delete(void * memory,const char * file,unsigned int
void * _vfxMemoryNew(size_t size,const char * file,unsigned int
# ifdef VFX_DEBUG_MEMORY
inline void * _cdecl operator new (size_t nSize,const char *
pFileName,int dwLine)
{ return _vfx_New(nSize,pFileName,dwLine); }
inline void * _cdecl operator new (size_t
nSize,std::nothrow_t,const char * pFileName,int dwLine)
{ return _vfx_New(nSize,pFileName,dwLine); }
inline void _cdecl operator delete (void * pMem,const char *
pFileName,int dwLine)
{ _vfx_Delete(pMem,pFileName,dwLine); }
inline void * _cdecl operator new [] (size_t nSize,const char *
pFileName,int dwLine)
{ return _vfx_New(nSize,pFileName,dwLine); }
inline void * _cdecl operator new [] (size_t
nSize,std::nothrow_t,const char * pFileName,int dwLine)
{ return _vfx_New(nSize,pFileName,dwLine); }
inline void _cdecl operator delete [] (void * pMem,const char *
pFileName,int dwLine)
{& _vfx_Delete(pMem,pFileName,dwLine); }
inline void * _cdecl operator new (size_t nSize)
{ return _vfx_New(nSize,0,0); }
inline void * _cdecl operator new (size_t
nSize,std::nothrow_t)
{ return _vfxMemoryNew(nSize,0,0); }
inline void _cdecl operator delete (void * pMem)
{ _vfx_Delete(pMem,0,0); }
inline void * _cdecl operator new [] (size_t nSize)
{ return _vfx_New(nSize,0,0); }
inline void * _cdecl operator new [] (size_t
nSize,std::nothrow_t)
{& return _vfxMemoryNew(nSize,0,0); }
inline void _cdecl operator delete [] (void * pMem)
{ _vfx_Delete(pMem,0,0); }
inline void * _cdecl operator new (size_t nSize)
{ return _vfx_New(nSize,0,0); }
inline void * _cdecl operator new (size_t
nSize,std::nothrow_t)
{ return _vfxMemoryNew(nSize,0,0); }
inline void _cdecl operator delete (void * pMem)
{ _vfx_Delete(pMem,0,0); }
inline void * _cdecl operator new [] (size_t nSize)
{& return _vfx_New(nSize,0,0); }
inline void * _cdecl operator new [] (size_t
nSize,std::nothrow_t)
{& return _vfxMemoryNew(nSize,0,0); }
inline void _cdecl operator delete [] (void * pMem)
{ _vfx_Delete(pMem,0,0); }
# endif //end VFX_DEBUG_MEMORY
# if VFX_DEBUG_MEMORY
# define VNEW new(__FILE__,__LINE__)
# define VNEW_NOTHROW new(std::nothrow,__FILE__,__LINE__)
# define VNEW new
# define VNEW_NOTHROW new(std::nothrow)
# endif //end VFX_DEBUG_MEMORY
# define VNEW new
# define VNEW_NOTHROW new(std::nothrow)
# endif //end _NOVNEW
#undef VFX_ASSERT
#include &cassert&
#define VFX_ASSERT assert
#undef VFX_TRACE
#define VFX_TRACE _vfxTrace
#undef VFX_LTRACE
#define VFX_LTRACE _vfxLevelTrace
#undef VFX_UNUSED
#define VFX_UNUSED(x)
#if _DEBUG
# undef VFX_VERIFY
# define VFX_VERIFY(f) VFX_ASSERT(f)
# undef VFX_ASSERT_VALID
# define VFX_ASSERT_VALID(p)
_vfxAssertValid(p,_DBG_WIDE(__FILE__),__LINE__)
# undef VFX_ASSERT_THIS
# define VFX_ASSERT_THIS(p)
_vfxAssertThis(p,_DBG_WIDE(__FILE__),__LINE__)
# undef VFX_TRACE0
# define VFX_TRACE0(sz) _vfxTrace(sz)
# undef VFX_TRACE1
# define VFX_TRACE1(sz,p0) _vfxTrace(sz,p0)
# undef VFX_TRACE2
# define VFX_TRACE2(sz,p1,p2) _vfxTrace(sz,p1,p2)
# undef VFX_TRACE3
# define VFX_TRACE3(sz,p1,p2,p3) _vfxTrace(sz,p1,p2,p3)
# undef VFX_TRACE4
# define VFX_TRACE4(sz,p1,p2,p3,p4) _vfxTrace(sz,p1,p2,p3,p4)
#else & // _DEBUG
# undef VFX_VERIFY
# define VFX_VERIFY(f) ((void)(f))
# undef VFX_ASSERT_VALID
# define VFX_ASSERT_VALID(p) ((void)0)
# undef VFX_ASSERT_THIS
# define VFX_ASSERT_THIS(p) ((void)0)
# undef VFX_TRACE0
# define VFX_TRACE0(sz)
# undef VFX_TRACE1
# define VFX_TRACE1(sz,p0)
# undef VFX_TRACE2
# define VFX_TRACE2(sz,p1,p2)
# undef VFX_TRACE3
# define VFX_TRACE3(sz,p1,p2,p3)
# undef VFX_TRACE4
# define VFX_TRACE4(sz,p1,p2,p3,p4)
#endif // !_DEBUG
//#ifndef __VFX_LOGO_FILE
//#define __VFX_LOGO_FILE "vfxlog.txt"
void __cdecl _vfxTraceA(LPCSTR lpszFormat, ...);
void __cdecl _vfxLevelTraceA(UINT_PTR level, LPCSTR lpszFormat,
void __cdecl _vfxTraceW(LPCWSTR lpszFormat, ...);
void __cdecl _vfxLevelTraceW(UINT_PTR level, LPCWSTR lpszFormat,
#ifdef UNICODE
# define _vfxTrace _vfxTraceW
# define _vfxLevelTrace _vfxLevelTraceW
# define _vfxTrace _vfxTraceA
# define _vfxLevelTrace _vfxLevelTraceA
#if __CPL_FULL_VER &
BOOL _vfxAssertValid(LPVOID p,LPCSTR lpszFileName,DWORD
BOOL _vfxAssertThis(LPVOID p,LPCSTR lpszFileName,DWORD
BOOL _vfxAssertValid(LPVOID p,LPCWSTR lpszFileName,DWORD
BOOL _vfxAssertThis(LPVOID p,LPCWSTR lpszFileName,DWORD
UINT_PTR _vfxGetTraceLevel();
void _vfxSetTraceLevel(UINT_PTR uLevel);
void _vfxSetTraceIO(class VFile_Base *);
inline void _vfxReportException(LPCSTR pStrResion,const
EXCEPTION_RECORD & SavedExpRecord,const CONTEXT
& SavedExpContext)
VFX_LTRACE(5, vT("%s\r\n")
vT("error 0x%8.8X at 0x%8.8X\r\n"),
pStrResion,
SavedExpRecord.ExceptionCode,
SavedExpRecord.ExceptionAddress);
#ifdef _WIN64
VFX_LTRACE(5, vT("RAX = 0x%p\r\n")
vT("RBX = 0x%p\r\n")
vT("RCX = 0x%p\r\n")
vT("RDX = 0x%p\r\n")
vT("RSI = 0x%p\r\n")
vT("RDI = 0x%p\r\n")
vT("RSP = 0x%p\r\n")
vT("RBP = 0x%p\r\n")
vT("RIP = 0x%p\r\n")
vT("R8 = 0x%p\r\n")
vT("R9 = 0x%p\r\n")
vT("R10 = 0x%p\r\n")
vT("R11 = 0x%p\r\n")
vT("R12 = 0x%p\r\n")
vT("R13 = 0x%p\r\n")
vT("R14 = 0x%p\r\n")
vT("R15 = 0x%p\r\n")
vT("EFL = 0x%p\r\n")
SavedExpContext.Rax,
SavedExpContext.Rbx,
SavedExpContext.Rcx,
SavedExpContext.Rdx,
SavedExpContext.Rsi,
SavedExpContext.Rdi,
SavedExpContext.Rsp,
SavedExpContext.Rbp,
SavedExpContext.Rip,
SavedExpContext.R8,
SavedExpContext.R9,
SavedExpContext.R10,
SavedExpContext.R11,
SavedExpContext.R12,
SavedExpContext.R13,
SavedExpContext.R14,
SavedExpContext.R15,
SavedExpContext.EFlags);
VFX_LTRACE(5, vT("EAX = 0x%8.8X\r\n")
vT("EBX = 0x%8.8X\r\n")
vT("ECX = 0x%8.8X\r\n")
vT("EDX = 0x%8.8X\r\n")
vT("ESI = 0x%8.8X\r\n")
vT("EDI = 0x%8.8X\r\n")
vT("ESP = 0x%8.8X\r\n")
vT("EBP = 0x%8.8X\r\n")
vT("EIP = 0x%8.8X\r\n")
vT("EFL = 0x%8.8X\r\n"),
SavedExpContext.Eax,
SavedExpContext.Ebx,
SavedExpContext.Ecx,
SavedExpContext.Edx,
SavedExpContext.Esi,
SavedExpContext.Edi,
SavedExpContext.Esp,
SavedExpContext.Ebp,
SavedExpContext.Eip,
SavedExpContext.EFlags);
#endif //end __VFX_DEBUG_H__
//--------------------------------
vfxdebug.cpp-------------------------------
// VictoryCore Code
// debuging and memory manager
// Author : lanzhengpeng(兰征鹏)
// More author :
// Create time :
// Modify time :
//-----------------------------------------------------------------------------
#include "stdafx.h"
#include &tchar.h&
#include &iostream&
#include &BaseTsd.h&
#include &WTypes.h&
#include &assert.h&
#define new VNEW
namespace __vfxdebug
UINT_PTR __VFX_TRACE_LEVEL = 0;
#if &defined(VFX_LOGO_FILE) ||
defined(VFX_MULT_LOGO_FILE)
class __vfxLogoFile
VFile_Base * m_pF
CRITICAL_SECTION m_
inline void Lock(){::EnterCriticalSection((CRITICAL_SECTION
*)&m_cs);}
inline void Unlock(){::LeaveCriticalSection((CRITICAL_SECTION
*)&m_cs);}
void SetIO(VFile_Base * pFile)
delete m_pF
m_pFile = pF
void OpenLogo()
ASSERT(m_pFile == NULL);
m_pFile = new VF
TCHAR buff[MAX_PATH];
GetModuleFileName(GetModuleHandle(NULL),buff,MAX_PATH);
_tcscat(buff,vT(".log"));
BOOL bOpened = TRUE;
#if &defined(VFX_MULT_LOGO_FILE)
if(!m_pFile-&Open(buff,VFile::modeWrite |
VFile::shareDenyNone))
m_pFile-&Open(buff,VFile::modeCreate |
VFile::modeWrite | VFile::shareDenyNone);
m_pFile-&Seek(0,VFile_Base::end);
__vfxLogoFile()
m_pFile = NULL;
::InitializeCriticalSection((CRITICAL_SECTION
~__vfxLogoFile()
destructor();
::DeleteCriticalSection((CRITICAL_SECTION
void destructor()
if(m_pFile != NULL)
m_pFile-&Flush();
m_pFile-&Close();
delete m_pF
virtual DWORD_PTR Write(const void* lpBuf, DWORD_PTR nCount)
if(m_pFile == NULL)
OpenLogo();
if(m_pFile != NULL)
return m_pFile-&Write(lpBuf,nCount);
__except(EXCEPTION_EXECUTE_HANDLER){
virtual BOOL Flush()
if(m_pFile != NULL)
return m_pFile-&Flush();
return FALSE;
__except(EXCEPTION_EXECUTE_HANDLER){
return FALSE;
__vfxLogoFile & __vfxgetlogofile()
static __vfxLogoFile __
//void __vfxDestructorOutputDebug()
// __vfxgetlogofile().destructor();
static time_t g_OutputDebugTime = 0;
static CHAR &g_szOutputDebugTime[32];
void __vfxOutputDebugStringA(LPCSTR lpOutputString)
::OutputDebugStringA(lpOutputString);
std::cout && lpOutputS
#if &defined(VFX_LOGO_FILE) ||
defined(VFX_MULT_LOGO_FILE)
time_t tNow = time(NULL);
if(g_OutputDebugTime != tNow)
g_OutputDebugTime = tN
tm * tmNow = localtime(&tNow);
sprintf(g_szOutputDebugTime,"[%.4d-%.2d-%.2d
%.2d:%.2d:%.2d]",
tmNow-&tm_year+1900,tmNow-&tm_mon+1,tmNow-&tm_mday,
tmNow-&tm_hour,tmNow-&tm_min,tmNow-&tm_sec);
__vfxgetlogofile().Lock();
__vfxgetlogofile().Write(g_szOutputDebugTime,21);
size_t n = strlen(lpOutputString);
if(n & 1 &&
lpOutputString[n - 1] == '\n' &&
lpOutputString[n - 2] != '\r')
__vfxgetlogofile().Write(lpOutputString,n - 1);
__vfxgetlogofile().Write("\r\n",2);
__vfxgetlogofile().Write(lpOutputString,n);
//__vfxgetlogofile().Flush();
__vfxgetlogofile().Unlock();
void __vfxOutputDebugStringW(LPCWSTR lpOutputString)
::OutputDebugStringW(lpOutputString);
std::cout && lpOutputS
#if &defined(VFX_LOGO_FILE) ||
defined(VFX_MULT_LOGO_FILE)
__vfxgetlogofile().Lock();
size_t n = wcslen(lpOutputString);
if(n & 1 &&
lpOutputString[n - 1] == L'\n' &&
lpOutputString[n - 2] != L'\r')
__vfxgetlogofile().Write(lpOutputString,n - 1);
__vfxgetlogofile().Write(L"\r\n",4);
__vfxgetlogofile().Write(lpOutputString,n);
//__vfxgetlogofile().Flush();
__vfxgetlogofile().Unlock();
UINT_PTR _vfxGetTraceLevel()
return __vfxdebug::__VFX_TRACE_LEVEL;
void _vfxSetTraceLevel(UINT_PTR uLevel)
__vfxdebug::__VFX_TRACE_LEVEL = uL
void _vfxSetTraceIO(class VFile_Base * pFile)
//__vfxdebug::__vfxgetlogofile().SetIO(pFile);
void __cdecl _vfxTraceA(LPCSTR lpszFormat, ...)
#if _DEBUG
va_list pA
va_start(pArgs,lpszFormat);
CHAR Tmp[1024];
int nBuf = ::_vsnprintf(Tmp,1024,lpszFormat,pArgs);
assert(nBuf & sizeof(Tmp));
#if &defined(VFX_LOGO_FILE) ||
defined(VFX_MULT_LOGO_FILE)
if(IsDebuggerPresent())
::OutputDebugStringA(Tmp);
__vfxdebug::__vfxOutputDebugStringA(Tmp);
::OutputDebugStringA(Tmp);
va_end(pArgs);
void __cdecl _vfxLevelTraceA(UINT_PTR level, LPCSTR lpszFormat,
if(level &= __vfxdebug::__VFX_TRACE_LEVEL)
va_list pA
va_start(pArgs,lpszFormat);
CHAR Tmp[1024];
int nBuf = ::_vsnprintf(Tmp,1024,lpszFormat,pArgs);
assert(nBuf & sizeof(Tmp));
__vfxdebug::__vfxOutputDebugStringA(Tmp);
va_end(pArgs);
void __cdecl _vfxTraceW(LPCWSTR lpszFormat, ...)
#if _DEBUG
va_list pA
va_start(pArgs,lpszFormat);
CHAR Tmp[1024];
WCHAR ttmp[1024];
int nBuf = ::_vsnwprintf(ttmp,1024,lpszFormat,pArgs);
assert(nBuf & sizeof(ttmp));
//VC对宽字符的调试信息支持不好 :-(
WideCharToMultiByte( CP_ACP, 0, ttmp, -1, Tmp, 1024, NULL, NULL
#if &defined(VFX_LOGO_FILE) ||
defined(VFX_MULT_LOGO_FILE)
if(IsDebuggerPresent())
::OutputDebugStringA(Tmp);
__vfxdebug::__vfxOutputDebugStringA(Tmp);
::OutputDebugStringA(Tmp);
va_end(pArgs);
void __cdecl _vfxLevelTraceW(UINT_PTR level, LPCWSTR lpszFormat,
if(level &= __vfxdebug::__VFX_TRACE_LEVEL)
va_list pA
va_start(pArgs,lpszFormat);
CHAR Tmp[1024];
WCHAR ttmp[1024];
int nBuf = ::_vsnwprintf(ttmp,1024,lpszFormat,pArgs);
assert(nBuf & sizeof(ttmp));
//VC对宽字符的调试信息支持不好 :-(
WideCharToMultiByte( CP_ACP, 0, ttmp, -1, Tmp, 1024, NULL, NULL
__vfxdebug::__vfxOutputDebugStringA(Tmp);
va_end(pArgs);
#if __CPL_FULL_VER &
BOOL _vfxAssertValid(LPVOID p,LPCSTR lpszFileName,DWORD
if(p == NULL || ::IsBadReadPtr(p,1) != 0)
CHAR Tmp[1024];
::sprintf(Tmp,"Assert Error At:\nfile:%s\nline:%d\nSelect Yes to
debug",lpszFileName,dwLine);
if(::MessageBoxA(NULL,Tmp,"VectoryCore Error",MB_YESNO |
MB_ICONERROR | MB_DEFBUTTON1 | MB_SYSTEMMODAL | MB_TOPMOST) ==
#ifdef _DEBUG
//_assert(0,(LPCSTR)lpszFileName,dwLine);
return TRUE;
return FALSE;
return FALSE;
BOOL _vfxAssertThis(LPVOID p,LPCSTR lpszFileName,DWORD
if(p == NULL || ::IsBadWritePtr(p,4) != 0)
CHAR Tmp[1024];
::sprintf(Tmp,"Assert Error At:\nfile:%s\nline:%d\nSelect Yes to
debug",lpszFileName,dwLine);
if(::MessageBoxA(NULL,Tmp,"VectoryCore Error",MB_YESNO |
MB_ICONERROR | MB_DEFBUTTON1 | MB_SYSTEMMODAL | MB_TOPMOST) ==
#ifdef _DEBUG
//_assert(0,(LPSTR)lpszFileName,dwLine);
return TRUE;
return FALSE;
return FALSE;
BOOL _vfxAssertValid(LPVOID p,LPCWSTR lpszFileName,DWORD
if(p == NULL || ::IsBadReadPtr(p,1) != 0)
WCHAR Tmp[1024];
::swprintf(Tmp,1024,L"Assert Error At:\nfile:%s\nline:%d\nSelect
Yes to debug",lpszFileName,dwLine);
if(::MessageBoxW(NULL,Tmp,L"VectoryCore Error",MB_YESNO |
MB_ICONERROR | MB_DEFBUTTON1 | MB_SYSTEMMODAL | MB_TOPMOST) ==
#ifdef _DEBUG
_wassert(0,lpszFileName,dwLine);
return TRUE;
return FALSE;
return FALSE;
BOOL _vfxAssertThis(LPVOID p,LPCWSTR lpszFileName,DWORD
if(p == NULL || ::IsBadWritePtr(p,4) != 0)
WCHAR Tmp[1024];
::swprintf(Tmp,1024,L"Assert Error At:\nfile:%s\nline:%d\nSelect
Yes to debug",lpszFileName,dwLine);
if(::MessageBoxW(NULL,Tmp,L"VectoryCore Error",MB_YESNO |
MB_ICONERROR | MB_DEFBUTTON1 | MB_SYSTEMMODAL | MB_TOPMOST) ==
#ifdef _DEBUG
_wassert(0,lpszFileName,dwLine);
return TRUE;
return FALSE;
return FALSE;
-----------------------------vfxmemory.h-------------------------------
// VictoryCore Code
// memory allocer
// NOTICE:
// 我希望vfxmemory.h vfxmemory.cpp是非常独立的两个文件
// 这两个文件的更改不要影响其他代码,也不依赖别的代码
// 这也是有内存分配的机制决定的
// Author : lanzhengpeng(兰征鹏)
// More author : renwind(任晓宇)
// Create time :
// Modify time :
授课时修改, 从引擎剥离, 去掉日志,平台相关等部分,
使代码易于理解
//-----------------------------------------------------------------------------
#ifndef __VFX_MEMORY_H__
#define __VFX_MEMORY_H__
#pragma once
#include &tchar.h&
#include &assert.h&
#include &time.h&
#include &crtdbg.h&
#if _DEBUG
# define VFX_DEBUG_MEMORY 1
//# define VFX_DEBUG_MEMORY 1
# undef VFX_DEBUG_MEMORY
namespace VFX_Memory
#pragma pack(push)
#pragma pack(4)
inline void * __alloc(size_t size)
{ return HeapAlloc(GetProcessHeap(),0,size); }
inline void __free(void * pmem)
{ HeapFree(GetProcessHeap(),0,pmem); }
inline void * __alloc(size_t size,LPCSTR file,DWORD line)
{ return HeapAlloc(GetProcessHeap(),0,size); }
// { return _malloc_dbg(size,_NORMAL_BLOCK,file,line); }
__align_size = 8,
__pool_size = 128,
__max_bytes = 256
inline size_t round_up(size_t bytes)
return (bytes + __align_size - 1) &
~((size_t)__align_size - 1);
template&class T&
class vfxMArray
size_t m_nS
size_t m_nN
vfxMArray()
:m_pBuffer(0),m_nSize(0),m_nNumber(0)
~vfxMArray()
{ m_nSize = m_nNumber = 0;__free(m_pBuffer); }
T * GetData()
{ return m_pB }
size_t GetNumber()
{ return m_nN }
T & operator [](size_t n)
return m_pBuffer[n];
void Add(T & ref);
template&class T&
void vfxMArray&T&::Add(T
if(m_nNumber &= m_nSize)
m_nSize += __pool_
T * pNew =
reinterpret_cast&T*&(__alloc(sizeof(T)
* m_nSize));
memcpy(pNew,m_pBuffer,m_nNumber * sizeof(T));
__free(m_pBuffer);
m_pBuffer = pN
m_pBuffer[m_nNumber] =
m_nNumber++;
class _small_cookie
#ifdef VFX_DEBUG_MEMORY
const char *
#ifdef VFX_DEBUG_MEMORY
_small_cookie *
char data[1];
class _large_cookie
#ifdef VFX_DEBUG_MEMORY
_large_cookie *
_large_cookie *
class __memory_
class small_alloc
static small_alloc * __psmall_
_small_cookie * pool_chunk[__max_bytes / __align_size];
vfxMArray&_small_cookie *&
#ifdef VFX_DEBUG_MEMORY
vfxMArray&size_t& sizeA
void Dump();
void dump_memory(_small_cookie * check,size_t size);
#endif //end VFX_DEBUG_MEMORY
small_alloc();
_small_cookie * alloc_pool(size_t size);
~small_alloc();
void destructor();
#ifdef VFX_DEBUG_MEMORY
void * alloc(size_t size,const char * file,unsigned int
void free(void * memory,const char * file,unsigned int line);
void Check();
void * alloc(size_t size);
void free(void * memory);
static small_alloc & getalloc()
{ return *__psmall_ }
friend __memory_
class large_alloc
static large_alloc * __plarge_
large_alloc();
#ifdef VFX_DEBUG_MEMORY
void Dump();
#endif //end _DEBUG
~large_alloc();
void destructor();
#ifdef VFX_DEBUG_MEMORY
void * alloc(size_t size,const char * file,unsigned int
void free(void * memory,const char * file,unsigned int line);
void Check();
void * alloc(size_t size);
void free(void * memory);
static large_alloc & getalloc()
{ return *__plarge_ }
friend __memory_
class __memory_init
__memory_init()
static large_alloc _large_
static small_alloc _small_
if(small_alloc::__psmall_alloc == 0)
small_alloc::__psmall_alloc = &_small_
large_alloc::__plarge_alloc = &_large_
#pragma pack(pop)
#endif //end __VFX_MEMORY_H__
--------------------------------vfxmemory.cpp----------------------
// VictoryCore Code
// memory allocer
// Author : lanzhengpeng(兰征鹏)
// More author :
// Create time :
// Modify time :
// 内存分配代码依赖一个全局变量。此全局变量析构的时候,CRT可能已经被(部分)销毁
// 导致在析构函数中不能使用CRT的相关函数。而在最后又需要报告内存信息,需
// 要使用到C运行库的_vsnprintf函数。
// 妥协的做法是在析构函数里不做任何事,而在DLL_PROCESS_DETACH时报告内存信息。
// 事实上的内存分配和错误报告输出相互依赖也导致问题,故错误输出也需要单独写
//-----------------------------------------------------------------------------
#include "stdafx.h"
#ifdef _MFC
#include &afx.h&
#include &windows.h&
#include "vfxmemory.h"
#include &cassert&
#include &new&
#include &stdio.h&
#if defined(_MSC_VER) && _MSC_VER
# define USE_STD std
# define USE_STD
#define vT(x) x
static void __cdecl __MemoryTrace(const char * lpszFormat,
#ifdef VFX_DEBUG_MEMORY
va_list pA
va_start(pArgs,lpszFormat);
char Tmp[1024];
int nBuf = _vsntprintf(Tmp,1024,lpszFormat,pArgs);
::OutputDebugStringA(Tmp);
va_end(pArgs);
namespace VFX_Memory
#ifdef _MT
static long g_memory_critical = 0;
void memory_lock()
if(InterlockedExchange(&g_memory_critical,1))
while(InterlockedExchange(&g_memory_critical,1))
void memory_unlock()
InterlockedExchange(&g_memory_critical,0);
class auto_memory_lock
auto_memory_lock()
{ memory_lock();}
~auto_memory_lock()
{ memory_unlock();}
#endif //end _MT
#ifdef VFX_DEBUG_MEMORY
const unsigned int c_uMalloc0xCC = 0xCCCCCCCC;
static size_t g_alloc_times = 0;
static __int64 g_alloc_break_times = -1;
static size_t g_memory_obj = 0;
static size_t g_memoey_used = 0;
static size_t g_memory_max = 0;
static int _vfxMemoryOutputReport();
#endif //end VFX_DEBUG_MEMORY
small_alloc * small_alloc::__psmall_alloc = 0;
small_alloc::small_alloc()
memset(pool_chunk,0,sizeof(pool_chunk));
small_alloc::~small_alloc()
destructor();
void small_alloc::destructor()
#ifdef VFX_DEBUG_MEMORY
_vfxMemoryOutputReport();
size_t size = poolArray.GetNumber();
_small_cookie ** p = poolArray.GetData();
for(size_t i=0;i&++i,++p)
__free(*p);
#endif //end VFX_DEBUG_MEMORY
_small_cookie * small_alloc::alloc_pool(size_t size)
size = round_up(size);
size_t newsize = round_up(size + sizeof(_small_cookie) -
sizeof(_small_cookie *)) + sizeof(unsigned);
_small_cookie * p = reinterpret_cast&_small_cookie
*&(__alloc(newsize * __pool_size));
_small_cookie * pp =
reinterpret_cast&_small_cookie*&(p);
_small_cookie *
for (size_t i=0;i&__pool_size-1;++i,pp=next)
reinterpret_cast&_small_cookie*&((INT_PTR)pp
+ newsize);
pp-&next =
pp-&size =
#ifdef VFX_DEBUG_MEMORY
pp-&file = 0;
pp-&line = 0;
pp-&id = (unsigned int)-1;
#endif //end VFX_DEBUG_MEMORY
pp-&next = 0;
pp-&size =
#ifdef VFX_DEBUG_MEMORY
pp-&file = 0;
pp-&line = 0;
pp-&id = (unsigned int)-1;
#endif //end VFX_DEBUG_MEMORY
poolArray.Add(p);
#ifdef VFX_DEBUG_MEMORY
sizeArray.Add(size);
#endif //end VFX_DEBUG_MEMORY
#ifdef VFX_DEBUG_MEMORY
void * small_alloc::alloc(size_t size,const char * file,unsigned
assert(size &= __max_bytes);
if(size &= 0) size = 1;
_small_cookie * &free_list = pool_chunk[(size - 1)
/ __align_size];
if(free_list == 0)
free_list = alloc_pool(size);
void * ret = free_list-&
free_list-&file =
free_list-&line =
free_list-&size =
free_list-&id = g_alloc_times++;
free_list-&dccc = c_uMalloc0xCC;
g_memoey_used += free_list-&
g_memory_obj++;
if(g_memory_max & g_memoey_used)
g_memory_max = g_memoey_
free_list = free_list-&
*(unsigned *)((INT_PTR)ret + size) = c_uMalloc0xCC;
void small_alloc::free(void * memory,const char * file,unsigned int
_small_cookie * pcook =
reinterpret_cast&_small_cookie
((INT_PTR)memory - sizeof(_small_cookie) + sizeof(_small_cookie
size_t size = pcook-&
assert(size &= __max_bytes);
if(pcook-&dccc !=
c_uMalloc0xCC)//前效验位有问题,很可能越界或错误的指针
__MemoryTrace(vT("%s(%d) : Verify pointer(0x%8.8x)
failed!!!\n"),file,line,memory);
if(IsBadReadPtr(pcook-&file,4) == 0)
__MemoryTrace(vT("%s(%d) : Verify pointer(0x%8.8x) failed!!! Alloc
%d\n"),pcook-&file,pcook-&line,memory,pcook-&id);
__MemoryTrace(vT("Unkown position : Verify pointer(0x%8.8x)
failed!!! Alloc ID : %d\n"),memory,pcook-&id);
UINT_PTR * pdccc =
reinterpret_cast&unsigned*&((INT_PTR)memory
if(*pdccc != c_uMalloc0xCC)//后效验位有问题,很可能越界或错误的指针
__MemoryTrace(vT("%s(%d) : Verify pointer(0x%8.8x)
failed!\n"),file,line,memory);
if(IsBadReadPtr(pcook-&file,4) == 0)
__MemoryTrace(vT("%s(%d) : Verify pointer(0x%8.8x) failed! Alloc ID
%d\n"),pcook-&file,pcook-&line,memory,pcook-&id);
__MemoryTrace(vT("Unkown position : Verify pointer(0x%8.8x) failed!
Alloc ID : %d\n"),memory,pcook-&id);
memset(memory,0xCC,size);
g_memory_obj--;
g_memoey_used -=
_small_cookie * & free_list =
pool_chunk[(pcook-&size - 1) / __align_size];
pcook-&next = free_
free_list =
pcook-&id = (unsigned int)-1;
void * small_alloc::alloc(size_t size)
if(size &= 0) size = 1;
_small_cookie * &free_list = pool_chunk[(size - 1)
/ __align_size];
if(free_list == 0)
free_list = alloc_pool(size);
free_list-&size =
void * ret = free_list-&
free_list = free_list-&
void small_alloc::free(void * memory)
_small_cookie * pcook =
reinterpret_cast&_small_cookie
((INT_PTR)memory - sizeof(_small_cookie) + sizeof(_small_cookie
_small_cookie * & free_list =
pool_chunk[(pcook-&size - 1) / __align_size];
pcook-&next = free_
free_list =
#endif //end VFX_DEBUG_MEMORY
#ifdef VFX_DEBUG_MEMORY
void small_alloc::dump_memory(_small_cookie * check,size_t
leak_size)
assert(leak_size & 0);
size_t size = round_up(leak_size + sizeof(_small_cookie) -
sizeof(_small_cookie *)) + sizeof(unsigned);
for(register int i = 0 ; i & __pool_
if (check-&id != (unsigned int)-1)
if(check-&file &&
IsBadReadPtr(check-&file,4) == 0)
__MemoryTrace(vT("%s(%d) : Memory leak! There have %d bytes memory
had not be delete. Alloc ID : %d\n")
,check-&file,check-&line,leak_size,check-&id);
__MemoryTrace(vT("Unkown position : Memory leak! There have %d
bytes memory had not be delete. Alloc ID : %d\n")
,leak_size,check-&id);
reinterpret_cast&_small_cookie*&((INT_PTR)check
void small_alloc::Dump()
for(unsigned int i = 0; i & poolArray.GetNumber();
dump_memory(poolArray[i],sizeArray[i]);
void small_alloc::Check()
for(size_t n=0; n&poolArray.GetNumber(); ++n)
size_t size = sizeArray[n];
size_t newsize = round_up(size + sizeof(_small_cookie) -
sizeof(_small_cookie *)) + sizeof(unsigned);
_small_cookie * pcook = poolArray[n];
for(int i=0; i&__pool_ ++i)
//前效验位有问题,很可能越界或错误的指针
if(pcook-&dccc != c_uMalloc0xCC
&& pcook-&id !=
(unsigned int)-1)
if(IsBadReadPtr(pcook-&file,4) == 0)
__MemoryTrace(vT("%s(%d) : Verify pointer(0x%8.8x) failed!!! Alloc
ID : %d\n"),
pcook-&file,pcook-&line,pcook-&data,pcook-&id);
__MemoryTrace(vT("Unkown position : Verify pointer(0x%8.8x)
failed!!! Alloc ID : %d\n"),
pcook-&data,pcook-&id);
unsigned int * pdccc = reinterpret_cast&unsigned
int*&(((INT_PTR)pcook-&data) +
pcook-&size);
//后效验位有问题,很可能越界或错误的指针
if(*pdccc != c_uMalloc0xCC &&
pcook-&id != (unsigned int)-1)
if(IsBadReadPtr(pcook-&file,4) == 0)
__MemoryTrace(vT("%s(%d) : Verify pointer(0x%8.8x) failed! Alloc ID
pcook-&file,pcook-&line,pcook-&data,pcook-&id);
__MemoryTrace(vT("Unkown position : Verify pointer(0x%8.8x) failed!
Alloc ID : %d\n"),
pcook-&data,pcook-&id);
pcook = (_small_cookie *)((INT_PTR)pcook + newsize);
#endif //end VFX_DEBUG_MEMORY
//-----------------------------------------------------------------------------
large_alloc * large_alloc::__plarge_alloc = 0;
large_alloc::large_alloc()
memset(&header,0,sizeof(header));
large_alloc::~large_alloc()
destructor();
void large_alloc::destructor()
#ifdef VFX_DEBUG_MEMORY
_vfxMemoryOutputReport();
#endif //end VFX_DEBUG_MEMORY
#ifdef VFX_DEBUG_MEMORY
void * large_alloc::alloc(size_t size,const char * file,unsigned
size = round_up(size);
_large_cookie * pcook =
reinterpret_cast&_large_cookie
(__alloc(size + sizeof(_large_cookie) + sizeof(int
*),file,line));
unsigned int * pdccc = reinterpret_cast&unsigned int
*&((INT_PTR)pcook-&cookie.data +
*pdccc = c_uMalloc0xCC;
pcook-&dccc = c_uMalloc0xCC;
pcook-&next = header.
pcook-&prev = &
if(header.next)
header.next-&prev =
header.next =
pcook-&cookie.file =
pcook-&cookie.line =
pcook-&cookie.size =
pcook-&cookie.id = g_alloc_times++;
g_memory_obj++;
g_memoey_used +=
if(g_memory_max & g_memoey_used)
g_memory_max = g_memoey_
return pcook-&cookie.
void large_alloc::free(void * memory,const char * file,unsigned int
_large_cookie * pcook =
reinterpret_cast&_large_cookie
((INT_PTR)memory - sizeof(_large_cookie) + sizeof(_large_cookie
if(pcook-&dccc !=
c_uMalloc0xCC)//前效验位有问题,很可能越界或错误的指针
__MemoryTrace(vT("%s(%d) : Verify pointer(0x%8.8x)
failed!!!\n"),file,line,memory);
if(IsBadReadPtr(pcook-&cookie.file,4) == 0)
__MemoryTrace(vT("%s(%d) : Verify pointer(0x%8.8x) failed!!! Alloc
%d\n"),pcook-&cookie.file,pcook-&cookie.line,memory,pcook-&cookie.id);
__MemoryTrace(vT("Unkown position : Verify pointer(0x%8.8x)
failed!!! Alloc ID :
%d\n"),memory,pcook-&cookie.id);
unsigned int * pdccc = reinterpret_cast&unsigned int
*&((INT_PTR)memory +
pcook-&cookie.size);
if(*pdccc != c_uMalloc0xCC)//后效验位有问题,很可能越界或错误的指针
__MemoryTrace(vT("%s(%d) : Verify pointer(0x%8.8x)
failed!\n"),file,line,memory);
if(IsBadReadPtr(pcook-&cookie.file,4) == 0)
__MemoryTrace(vT("%s(%d) : Verify pointer(0x%8.8x) failed! Alloc ID
%d\n"),pcook-&cookie.file,pcook-&cookie.line,memory,pcook-&cookie.id);
__MemoryTrace(vT("Unkown position : Verify pointer(0x%8.8x) failed!
Alloc ID : %d\n"),memory,pcook-&cookie.id);
memset(memory,0xCC,pcook-&cookie.size);
g_memory_obj--;
g_memoey_used -= pcook-&cookie.
if(pcook-&prev)
pcook-&prev-&next =
if(pcook-&next)
pcook-&next-&prev =
__free(pcook);
void * large_alloc::alloc(size_t size)
_large_cookie * pcook =
reinterpret_cast&_large_cookie
(__alloc(size + sizeof(_large_cookie) - sizeof(_small_cookie
pcook-&cookie.size =
return (pcook == 0) ? 0 : pcook-&cookie.
void large_alloc::free(void * memory)
_large_cookie * pcook =
reinterpret_cast&_large_cookie
((INT_PTR)memory - sizeof(_large_cookie) + sizeof(_small_cookie
__free(pcook);
#endif //end VFX_DEBUG_MEMORY
#ifdef VFX_DEBUG_MEMORY
void large_alloc::Dump()
_large_cookie * p = header.
if(p-&cookie.file)
__MemoryTrace(vT("%s(%d) : Memory leak! There have %d bytes(%d K)
memory had not be delete. Alloc ID : %d\n")
,p-&cookie.file,p-&cookie.line,p-&cookie.size,(p-&cookie.size
+ 1023) / 1024,p-&cookie.id);
__MemoryTrace(vT("Unkown position(0x%8.8x) : Memory leak! There
have %d bytes(%d K) memory had not be delete. Alloc ID :
,p-&cookie.data,p-&cookie.size,(p-&cookie.size
+ 1023) / 1024,p-&cookie.id);
if(p-&dccc !=
c_uMalloc0xCC)//前效验位有问题,很可能越界或错误的指针
if(IsBadReadPtr(p,p-&cookie.size) == 0)
__MemoryTrace(vT("%s(%d) : Verify pointer(0x%8.8x) failed!!! Alloc
ID : %d\n")
,p-&cookie.file,p-&cookie.line,p-&cookie.data,p-&cookie.id);
__MemoryTrace(vT("Unkown position : Verify pointer(0x%8.8x)
failed!!! Alloc ID : %d\n")
,p-&cookie.data,p-&cookie.id);
unsigned int * pdccc = reinterpret_cast&unsigned int
*&((INT_PTR)p-&cookie.data +
p-&cookie.size);
if(*pdccc != c_uMalloc0xCC)//后效验位有问题,很可能越界或错误的指针
if(IsBadReadPtr(p,p-&cookie.size) == 0)
__MemoryTrace(vT("%s(%d) : Verify pointer(0x%8.8x) failed! Alloc ID
,p-&cookie.file,p-&cookie.line,p-&cookie.data,p-&cookie.id);
__MemoryTrace(vT("Unkown position : Verify pointer(0x%8.8x) failed!
Alloc ID : %d\n")
,p-&cookie.data,p-&cookie.id);
void large_alloc::Check()
_large_cookie * p = header.
if(p-&dccc !=
c_uMalloc0xCC)//前效验位有问题,很可能越界或错误的指针
if(IsBadReadPtr(p,p-&cookie.size) == 0)
__MemoryTrace(vT("%s(%d) : Verify pointer(0x%8.8x) failed!!! Alloc
ID : %d\n")
,p-&cookie.file,p-&cookie.line,p-&cookie.data,p-&cookie.id);
__MemoryTrace(vT("Unkown position : Verify pointer(0x%8.8x)
failed!!! Alloc ID : %d\n")
,p-&cookie.data,p-&cookie.id);
unsigned int * pdccc = reinterpret_cast&unsigned int
*&((INT_PTR)p-&cookie.data +
p-&cookie.size);
if(*pdccc != c_uMalloc0xCC)//后效验位有问题,很可能越界或错误的指针
if(IsBadReadPtr(p,p-&cookie.size) == 0)
__MemoryTrace(vT("%s(%d) : Verify pointer(0x%8.8x) failed! Alloc ID
,p-&cookie.file,p-&cookie.line,p-&cookie.data,p-&cookie.id);
__MemoryTrace(vT("Unkown position : Verify pointer(0x%8.8x) failed!
Alloc ID : %d\n")
,p-&cookie.data,p-&cookie.id);
#endif //end VFX_DEBUG_MEMORY
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//static large_alloc large_alloc::getalloc();
//static small_alloc small_alloc::getalloc();
#ifdef VFX_DEBUG_MEMORY
static int _vfxMemoryOutputReport()
if(g_memory_max & 0)
__MemoryTrace(vT("\n"));
if(g_memory_obj & 0)
__MemoryTrace(vT("Memory leak : There have %d objects and %d
bytes(%d K) memory had not be delete!\n")
,g_memory_obj,g_memoey_used,(g_memoey_used + );
__MemoryTrace(vT("Max memory used : %u bytes(%d K)\n")
,g_memory_max,(g_memory_max + 1023) / 1024);
g_memory_max = 0;&
__MemoryTrace(vT("\n"));
& return 0;
#endif //end VFX_DEBUG_MEMORY
void _vfxDestructorMemory()
#ifdef VFX_DEBUG_MEMORY
small_alloc::getalloc().destructor();
large_alloc::getalloc().destructor();
#endif //end VFX_DEBUG_MEMORY
using namespace VFX_M
void * _vfxMemoryNew(size_t size,const char * file,unsigned int
static __memory_init memory_
#ifdef _MT
auto_memory_
#endif //end _MT
#ifdef VFX_DEBUG_MEMORY
if(g_alloc_times == g_alloc_break_times)
__asm int 3;
if(size & __max_bytes)
return large_alloc::getalloc().alloc(size,file,line);
return small_alloc::getalloc().alloc(size,file,line);
if(size & __max_bytes)
return large_alloc::getalloc().alloc(size);
return small_alloc::getalloc().alloc(size);
#endif //end VFX_DEBUG_MEMORY
void _vfxMemoryDelete(void * memory,const char * file,unsigned int
if(memory == 0)
#ifdef _MT
auto_memory_
#endif //end _MT
_small_cookie * p = reinterpret_cast&_small_cookie
((INT_PTR)memory - sizeof(_small_cookie) + sizeof(_small_cookie
#ifdef VFX_DEBUG_MEMORY
if(p-&size & __max_bytes)
large_alloc::getalloc().free(memory,file,line);
small_alloc::getalloc().free(memory,file,line);
if(p-&size & __max_bytes)
large_alloc::getalloc().free(memory);
small_alloc::getalloc().free(memory);
#endif //end VFX_DEBUG_MEMORY
void _vfxMemoryReport()
#if VFX_DEBUG_MEMORY
#ifdef _MT
auto_memory_
#endif //end _MT
large_alloc::getalloc().Check();
small_alloc::getalloc().Check();
void _vfxMemorySetBreak(size_t n)
#ifdef VFX_DEBUG_MEMORY
g_alloc_break_times =
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。}

我要回帖

更多关于 gdb 查看内存泄露 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信