当前位置:网站首页>Memory leaks and common solutions
Memory leaks and common solutions
2022-07-29 08:39:00 【Full stack programmer webmaster】
Hello everyone , I meet you again , I'm the king of the whole stack , I wish every programmer can learn more languages .
The reason for writing this article is that I spent a lot of energy on the mature code some time ago memory leak problem . The purpose of writing this is to hope that we should develop good coding habits , Try to avoid this problem , Because when you deal with such problems in front of a large piece of code , No doubt add at this time � The cost and difficulty of solving . To be exact, it is a remedial measure .
1. What is memory leak (memory leak)?
It refers to the situation that the program fails to release the memory that is no longer used due to negligence or error . A memory leak is not a physical loss of memory , But after the application allocates some memory , Because of design mistakes , Lost control of this segment of memory , So it's a waste of memory .
A memory leak is a particular type of unintentional memory consumption by a computer program where the program fails to release memory when no longer needed. This condition is normally the result of a bug in a program that prevents it from freeing up memory that it no longer needs.This term has the potential to be confusing, since memory is not physically lost from the computer. Rather, memory is allocated to a program, and that program subsequently loses the ability to access it due to program logic flaws.
2. about C and C++ No such thing Garbage Collection In terms of language , We focus on two types of memory leaks :
Heap memory leak (Heap leak). Memory allocation refers to the basis for the execution of the program malloc,realloc new Wait for a piece of memory allocated from the heap , After that, you must call the corresponding free perhaps delete Delete . Suppose the design error of the program causes this part of memory not to be released , Then this memory will not be used after that , It will produce Heap Leak.
System resource leakage (Resource Leak). It mainly refers to that the program uses the resources allocated by the system Bitmap,handle ,SOCKET Wait until the corresponding function is not used , Leading to a waste of system resources , Serious can lead to reduced system performance , The system execution is unstable .
3. How to solve memory leak ?
The difficulty of memory leakage lies in 1. The compiler cannot find these problems .2. These errors can only be caught during execution , These errors have no obvious symptoms , Now is now, now is now .3. For terminal development users such as mobile phones , Especially difficult . Here are three ways to solve memory leaks :
First of all , Good coding habits , Try to use memory in program segments , Memory leak detected . When the program is stable , When checking for memory leaks , Undoubtedly add � The difficulty and complexity of elimination .
Using memory allocation functions , Remember to use the function you want to use to release , Once used .
Heap memory:
malloc\realloc ------ free
new \new[] ---------- delete \delete[]
GlobalAlloc------------GlobalFree
Pay special attention to memory leaks of array objects
MyPointEX *pointArray =new MyPointEX [100];
Its deletion form is :
delete []pointArray
Resource Leak : Look carefully at the usage of system resources before using , Prevent misuse or forgetting to release system resources .
Let's see MSDN Last example of creating a font :
RECT rect;
HBRUSH hBrush;
FONT hFont;
hdc = BeginPaint(hWnd, &ps);
hFont = reateFont(48,0,0,0,FW_DONTCARE,FALSE,TRUE,FALSE,DEFAULT_CHARSET,OUT_OUTLINE_PRECIS, CLIP_DEFAULT_PRECIS,CLEARTYPE_QUALITY, VARIABLE_PITCH,TEXT("Impact"));
SelectObject(hdc, hFont);
SetRect(&rect, 100,100,700,200);
SetTextColor(hdc, RGB(255,0,0));
DrawText(hdc, TEXT(“Drawing Text with Impact”), -1,&rect, DT_NOCLIP);
DeleteObject(hFont);
EndPaint(hWnd, &ps);
Suppose you forget to release the font after using , This leads to resource leakage .
Pay particular attention to system objects based on reference counting , Because only its reference count is 0 when , The object can be deleted correctly . And there are new system resources generated during its use , After use , Suppose it is not deleted in time , Will affect its reference count .
IDNS *m_pDns//define a DNS object.
If(NULL == m_pDns)
{
IEnv_CreateInstance (m_pEnv,AEECLSID_DNS,(void **) (&m_pDns))
}
If(m_pDns)
{
Char szbuff[256];
IDNS_AddQuestions(M_pDns,AEEDNSTYPE_A,ADDDNSCLASS_IN,szbuff);
IDNS_Start(m_pDns,this);
const AEEDNSResponse * pDnsResponse = NULL;
IDNS_GetResponse(pMe->m_pDns, &pDnsResponse);
…………………………………………………………
…………………………………………………………..
………………………………………………………..
}
DNS_Release(pMe->m_pDns);// When the program is executed to this point , Its return value is not 0, yes 1, It means that the program has generated a memory leak , The system already has a DNS The generated kernel object is not released , And when this code is executed many times , Memory leaks will continue to add �……..
m_pDns=NULL;
}
It doesn't look very intuitive , Careful analysis will find , object pDnsResponse It's from m_pDns Generate new object, therefore m_pDns The reference count of will be added �, So after using pDnsResponse, should release This object returns its reference count to normal .
For resource , You can also use RAII,RAII(Resource acquisition is initialization) Resource acquisition is initialization , It is a very easy Technology , utilize C++ The concept of object lifecycle to control program resources , For example, memory. , File handle , Network connection and audit trail (audit trail) etc. .RAII The basic technical principle of is very easy. If you want to keep track of an important resource , So create an object , And associate the life cycle of resources with the life cycle of objects . In this way , Can use C++ Sophisticated object management facilities to manage resources .( It's still in good condition )
example 2:
Struct ITypeface *pTypeface;
if (pTypeface)
{
IANY_CreateInstance(g_pApplet->m_pIShell,AEECLSID_BTFETypeface,void**)& Typeface);
}
Next, we can create fonts from this interface , example
IHFont **pihf=NULL;
ITypeface_NewFontFromFile(ITypeface,……,&pihf).
ITypeface_NewFontFrommemory(ITypeface,……..,&pihf)
ITypeface_NewFontFromClassID(IType,……,&pihf)
But remember , These fonts must be release fall , Otherwise, in the end iTypeface The reference count of is the number of fonts you didn't delete at last .
second , heavy load new and delete. This is also a common method in the coding process .
The following is a simple sample To illustrate .
memchecker.h
structMemIns
{
void * pMem;
int m_nSize;
char m_szFileName[256];
int m_nLine;
MemIns * pNext;
};
classMemManager
{
public:
MemManager();
~MemManager();
private:
MemIns *m_pMemInsHead;
int m_nTotal;
public:
static MemManager* GetInstance();
void Append(MemIns *pMemIns);
void Remove(void *ptr);
void Dump();
};
void *operatornew(size_tsize,constchar*szFile, int nLine);
void operatordelete(void*ptr,constchar*szFile, int nLine);
void operatordelete(void*ptr);
void*operatornew[] (size_tsize,constchar*szFile,int nLine);
void operatordelete[](void*ptr,constchar*szFile, int nLine);
void operatordelete[](void *ptr);
memechecker.cpp
#include"Memchecher.h"
#include<stdio.h>
#include<malloc.h>
#include<string.h>
MemManager::MemManager()
{
m_pMemInsHead=NULL;
m_nTotal=NULL;
}
MemManager::~MemManager()
{
}
voidMemManager::Append(MemIns *pMemIns)
{
pMemIns->pNext=m_pMemInsHead;
m_pMemInsHead = pMemIns;
m_nTotal+= m_pMemInsHead->m_nSize;
}
voidMemManager::Remove(void *ptr)
{
MemIns * pCur = m_pMemInsHead;
MemIns * pPrev = NULL;
while(pCur)
{
if(pCur->pMem ==ptr)
{
if(pPrev)
{
pPrev->pNext =pCur->pNext;
}
else
{
m_pMemInsHead =pCur->pNext;
}
m_nTotal-=pCur->m_nSize;
free(pCur);
break;
}
pPrev = pCur;
pCur = pCur->pNext;
}
}
voidMemManager::Dump()
{
MemIns * pp = m_pMemInsHead;
while(pp)
{
printf( "File is %s\n", pp->m_szFileName );
printf( "Size is %d\n", pp->m_nSize );
printf( "Line is %d\n", pp->m_nLine );
pp = pp->pNext;
}
}
voidPutEntry(void *ptr,intsize,constchar*szFile, int nLine)
{
MemIns * p = (MemIns *)(malloc(sizeof(MemIns)));
if(p)
{
strcpy(p->m_szFileName,szFile);
p->m_nLine = nLine;
p->pMem = ptr;
p->m_nSize = size;
MemManager::GetInstance()->Append(p);
}
}
voidRemoveEntry(void *ptr)
{
MemManager::GetInstance()->Remove(ptr);
}
void *operatornew(size_tsize,constchar*szFile, int nLine)
{
void * ptr = malloc(size);
PutEntry(ptr,size,szFile,nLine);
return ptr;
}
voidoperatordelete(void *ptr)
{
RemoveEntry(ptr);
free(ptr);
}
void operatordelete(void*ptr,constchar * file, intline)
{
RemoveEntry(ptr);
free(ptr);
}
void*operatornew[] (size_tsize,constchar* szFile,intnLine)
{
void * ptr = malloc(size);
PutEntry(ptr,size,szFile,nLine);
return ptr;
}
void operatordelete[](void *ptr)
{
RemoveEntry(ptr);
free(ptr);
}
void operatordelete[](void*ptr,constchar*szFile,intnLine)
{
RemoveEntry(ptr);
free(ptr);
}
#definenewnew(__FILE__,__LINE__)
MemManagerm_memTracer;
MemManager*MemManager::GetInstance()
{
return &m_memTracer;
}
void main()
{
int *plen =newint ;
*plen=10;
delete plen;
char *pstr=newchar[35];
strcpy(pstr,"hello memory leak");
m_memTracer.Dump();
return ;
}
The main idea is to manage the allocated memory in the form of a linked list , Delete from the linked list after use , At the end of the program can check to change the list , It records the files with memory leaks , The number of lines in the file and the size of the leak .
Third ,Boost Medium smart pointer( To be in good condition , Combined with your suggestions )
Fourth , Some common tool plug-ins , See my Blog Related articles in .
4. Memory leakage leads to the topic of memory overflow :
The so-called memory overflow is that the memory you require to allocate exceeds what the system can give you , The system can't meet the demand , Then there will be a memory overflow problem .
Common overflows mainly include :
Memory allocation failed , It was used .
The solution often used is , Check that the pointer is... Before using memory NULL. Hypothetical pointer p Is the parameter of the function , Then use... At the entry of the function assert(p!=NULL) Inspection . Let's assume that malloc or new To apply for memory , Should use the if(p==NULL) or if(p!=NULL) Do error proofing .
Memory allocation was successful , But reference it before initialization .
Memory allocation successful and initialized , But operations cross the boundaries of memory .
For example, subscripts often occur when using arrays “ many 1” perhaps “ Less 1” The operation of . Especially in for In loop statement , The number of cycles is very easy mistake , Causes array operations to be out of bounds .
Use free or delete After releasing memory , The pointer is not set to NULL. Cause to produce “ Wild pointer ”.
The object calling relationship in the program is too complex , It's really difficult to figure out whether an object has released memory , At this time, the data structure should be designed again , Fundamentally solve the confusion of object management .( But I feel it deeply , ha-ha )
Don't forget to initialize arrays and dynamic memory . Prevent uninitialized memory from being used as a right value .
Publisher : Full stack programmer stack length , Reprint please indicate the source :https://javaforall.cn/118606.html Link to the original text :https://javaforall.cn
边栏推荐
- Source code compilation pytorch pit
- QT version of Snake game project
- Several ways of debugging support under oneos
- Data is the main body of future world development, and data security should be raised to the national strategic level
- Gan: generate adversarial networks
- Clion+opencv+aruco+cmake configuration
- 多重背包,朴素及其二进制优化
- GBase 8s数据库有哪些备份恢复方式
- BI data analysis practitioners learn financial knowledge from scratch? What introductory books are recommended
- Hal learning notes - Advanced timer of 7 timer
猜你喜欢
Week 1 task deep learning and pytorch Foundation
User identity identification and account system practice
QT learning: use non TS files such as json/xml to realize multilingual internationalization
node:文件写入数据(readFile、writeFile),覆盖与增量两种模式
A little knowledge [synchronized]
Hc-sr04 use method and routine of ultrasonic ranging module (STM32)
Selenium actual combat case crawling JS encrypted data
MySQL statement mind map
BI data analysis practitioners learn financial knowledge from scratch? What introductory books are recommended
Requests library simple method usage notes
随机推荐
英语高频后缀
优秀的Allegro Skill推荐
Arfoundation starts from scratch 5-ar image tracking
7.3-function-templates
To create a thread pool for the rate, start the core thread
Day6: using PHP to write landing pages
状态压缩dp
谷歌浏览器免跨域配置
深度学习(1):银行客户流失预测
2022 spsspro certification cup mathematical modeling problem B phase II scheme and post game summary
Chrony time synchronization
集群使用规范
ML.NET相关资源整理
Vs2019 compilation cryengine failure problem handling
HC-SR04超声波测距模块使用方法和例程(STM32)
Virtual augmentation and reality Part 2 (I'm a Firebird)
C language -- 23 two-dimensional array
(视频+图文)机器学习入门系列-第3章 逻辑回归
多重背包,朴素及其二进制优化
为了速率创建线程池,启动核心线程