查找内存泄漏的方式

(原创不易,如需转载,请注明出处)

所有的内存泄漏,就是一个原因,分配内存后没有释放。

智能指针是通过在某些结构体(类)中增加一个计数模块,如果有引用,计数模块加一,如果某个地方释放引用,那么计数模块就减一,直到计数为零,智能指针能自动释放内存。

那么,如果没有智能指针模块,那么为了防止内存泄漏,一定要规范内存分配与释放的原则。我的个人原则就是谁申请,谁释放。在同一个函数内申请和释放。当然,在实际情况中,必然会出现这边申请,但是不能马上释放的情况,比如对某些数据在程序启动的时候需要初始化,那就讲究一个对称原则,在哪一层申请,就在程序的哪一层释放,这种情况就比较考验开发者的能力了。

万一你接手了一个垃圾代码,申请与释放比较随心所欲,那么出现内存泄漏,你就需要相应的一些手法了。我这里整理了几段代码,在我实际上检查内存泄漏的时候,还是非常有用的。代码如下:

 

// DetectMem.h
#ifndef _DETECT_MEM_H_
#define _DETECT_MEM_H_
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
extern FILE* fp;

int DetectInit(const char *chPath);

int DetectunInit();

#define RECORDINGMEM(addr)	\
{\
	char chInfo[1024]={0};	\
	sprintf(chInfo,"0x%08X\t%d\t%s\n",addr,__LINE__,__FILE__);	\
	fwrite(chInfo,1,strlen(chInfo),fp);	\
}

#define RECORDING_MALLOC(addr)	\
{\
	char chInfo[1024]={0};	\
	sprintf(chInfo,"malloc\t0x%08X\t%d\t%s\n",addr,__LINE__,__FILE__);	\
	fwrite(chInfo,1,strlen(chInfo),fp);	\
}

#define RECORDING_FREE(addr)	\
{\
	char chInfo[1024]={0};	\
	sprintf(chInfo,"free\t0x%08X\t%d\t%s\n",addr,__LINE__,__FILE__);	\
	fwrite(chInfo,1,strlen(chInfo),fp);	\
}

#define RECORDINLINE()	\
{   \
    char chInfo[1024]={"---------------------------"};\
    fwrite(chInfo,1,strlen(chInfo),fp);	\
}

#endif // !_DETECT_MEM_H_

// detectMem.c
#include "DetectMem.h"
FILE* fp = NULL;
int DetectInit(const char *chPath)
{
	if (fp)
	{
		return -1;
	}

	fp = fopen(chPath, "wb+");
	if (!fp)
	{
		return -2;
	}
	return 0;
}

int DetectunInit()
{
	int nRet = 0;
	if (!fp)
	{
		return -1;
	}

	nRet = fclose(fp);
	if (!nRet)
	{
		return -2;
	}
	fp = NULL;
	return 0;
}

在使用之前,先初始化一下,用于初始化保存日志的地址,然后再通过使用宏模块,实现内存的记录,最后释放一下,保存文件。根据日志从上往下分析内存的申请与释放情况。

 

### 回答1: JProfiler 是一款功能强大的 Java 应用程序性能分析工具,可以用于查找内存泄漏问题。下面是使用 JProfiler 查找内存泄漏问题的步骤: 1. 启动应用程序并将其与 JProfiler 连接。在 JProfiler 中,选择 "Session" -> "New Session" -> "Attach to a running JVM",然后选择要连接的应用程序和相应的 JVM。 2. 在 JProfiler 的 "Control Center" 窗口中选择 "Memory" 选项卡,并选择 "Recording Settings" 子选项卡。在这里,您可以设置内存分析的一些参数,例如记录时长、对象数量等。 3. 开始记录内存使用情况。单击 "Start Recording" 按钮,JProfiler 将开始记录内存使用情况。 4. 执行一些操作,以便应用程序尽可能多地使用内存。例如,执行一些繁重的操作或操作大量数据的任务。 5. 停止内存记录并分析结果。在 "Memory" 选项卡中,选择 "Heap Walker" 子选项卡。这将打开一个新窗口,显示应用程序中的对象。 6. 使用 "Show Dominator Tree" 按钮查看内存使用情况最高的对象。该按钮位于 "Heap Walker" 窗口的工具栏中。这将显示占用内存最多的对象及其相关引用。 7. 识别内存泄漏查找可能引起内存泄漏的对象,并分析其引用关系。通过查看该对象的引用链,您可以确定是否存在任何对象持有了不必要的引用,导致这些对象不能被垃圾回收。 8. 通过修复代码中的问题来解决内存泄漏。找到代码中存在的问题,例如未正确释放对象或持有不必要的引用,并进行修复。 总之,使用 JProfiler 可以帮助您快速有效地识别内存泄漏问题并解决它们,从而提高应用程序的性能和稳定性。 ### 回答2: JProfiler是一种强大的Java性能分析工具,可以帮助定位和解决内存泄漏问题。下面是使用JProfiler来查找内存泄漏问题的步骤: 1. 启动目标应用程序和JProfiler。 2. 在JProfiler中选择“内存”选项卡。这将显示当前应用程序的内存使用情况。 3. 监控应用程序的内存使用情况,特别关注内存增长趋势。如果你发现内存占用总是增加而没有被释放,那么可能存在内存泄漏。 4. 在JProfiler中选择“快照”选项卡,然后点击“操作”按钮旁边的相机图标。这将创建一个内存快照,用于后续分析。 5. 在“快照”选项卡中选择“直方图”。这将显示应用程序中各个对象类型的内存使用情况。 6. 搜索大量占用内存的对象,特别是那些没有被及时释放的对象。通过查看对象的引用链,可以判断是否存在内存泄漏的可能。 7. 确定潜在的内存泄漏点后,可以使用JProfiler提供的其他功能进行进一步的内存泄漏分析。比如,可以使用线程分析来确定是否存在线程泄漏,使用内存分配跟踪来查找内存分配过程中的问题等。 8. 根据分析结果制定相应的解决方案,修复内存泄漏问题并重新测试应用程序。 9. 重复进行上述步骤,直到解决所有内存泄漏问题。 总的来说,使用JProfiler可以通过监控和分析内存使用情况,找出内存泄漏的根本原因,并提供相应的解决方案。它是一个非常有用的工具,可以提升应用程序的性能和稳定性。 ### 回答3: JProfiler是一款功能强大的Java性能分析工具,可以帮助我们定位和解决内存泄露的问题。 首先,使用JProfiler进行内存泄露的分析,我们可以通过以下几个步骤来进行操作。 第一步,打开JProfiler工具,并连接到我们想要分析的Java应用程序。 第二步,选择“内存”标签,进入内存分析界面。 第三步,开始记录内存数据。点击左上角的“开始记录内存数据”按钮,工具会开始记录内存使用情况。 第四步,进行快照分析。我们可以手动触发内存快照,或者选择自动快照。在快照分析界面,可以找到堆中存在的对象,并对其进行分析。 第五步,查找内存泄露的原因。我们可以通过查看对象的引用路径,找出哪些对象存在内存泄露。JProfiler会显示对象的引用关系,我们可以根据这些信息来定位内存泄露的问题。 第六步,确定内存泄露的根源,并解决问题。通过分析对象的引用路径,我们可以找到导致内存泄露的具体原因。然后,我们可以根据问题的性质采取相应的解决方法,比如释放无用的对象引用,或者进行垃圾回收优化等。 最后,我们可以使用JProfiler的监控功能,实时查看内存的使用情况,以及进行性能优化。通过不断的分析和优化,可以有效地解决内存泄露问题,提升应用程序的性能和稳定性。 总结来说,使用JProfiler可以帮助我们快速定位和解决内存泄露的问题,提高应用程序的性能和稳定性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值