用 .NET Memory Profiler 跟踪.net 应用内存使用情况--基本应用篇(转)
.net 框架号称永远不会发生内存泄漏,原因是其引入了内存回收的机制。但实际应用中,往往我们分配了对象但没有释放指向该对象的引用,导致对象永远无法释放。最 常见的情况就是给对象添加了事件处理函数,但当不再使用该对象时却没有将该函数从对象的事件handler中减掉。另外如果分配了非托管内存,而没有手工 释放,GC同样无能为力。所以当.net应用发生内存泄漏后如何跟踪应用的内存使用情况,定位到程序设计中的缺陷显得非常重要。本文将介绍通过.NET Memory Profiler来跟踪.net应用的内存泄漏,为定位.net应用内存问题提供一个解决途径。
.NET Memory Profiler是一款强大的.net 内存跟踪和优化工具。该工具目前可以对一下4种.net应用进行内存跟踪。
- 基本应用 例如winform, console application等
- ASP.net 应用
- WPF应用
- Window 服务
本篇将通过对以下三种内存的跟踪来阐述如何使用该工具对基本.net应用程序进行内存的跟踪。三种内存包括:
- 托管内存
- 线程托管内存
- 非托管内存
在开始之前,先需要建立环境。
我采用.NET Memory Profiler V3.1.307 版本进行测试。安装完后需要新建一个项目,由于我们需要测
.net基本应用,所以新建项目时选择Standalone application. 点击next后,输入要测试的.net 应用的路径和参数。
然后按下 finish.项目就建立完成了。
测试程序是我编写的,编译后生成TestMemorySize.exe 这个控制台应用程序。下载地址
代码如下
主程序等待用户输入,输入m,t,u 分别是增加托管内存,创建一个自动增加托管内存的线程,增加非托管内存。
输入d,释放主线程创建的托管内存对象。
using System;
using System.Collections.Generic;
using System.Text;
namespace TestMemorySize
{
class Program
{
static void Main(string[] args)
{
MemoryInc memoryInc = new MemoryInc();
while (true)
{
long memorysize = System.Diagnostics.Process.GetCurrentProcess().PagedMemorySize64;
Console.WriteLine(string.Format("PagedMemorySize:{0}MB", memorysize / (*)));
Console.WriteLine(string.Format("ManagedMemIncTimes:{0}", memoryInc.ManagedMemIncTimes));
Console.WriteLine(string.Format("UnmanagedMemIncTimes:{0}", memoryInc.UnmanagedMemIncTimes));
String cmd = Console.ReadLine();
switch (cmd)
{
case "d":
memoryInc = new MemoryInc();
GC.Collect();
break;
case "m":
memoryInc.IncManagedMemory();
break;
case "u":
memoryInc.IncUnmanagedMemory();
break;
case "t":
MemoryLeakThread thread = new MemoryLeakThread();
break;
case "l":
break;
}
}
}
}
}
MemoryInc 是一个增加托管内存和非托管内存的类。
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
namespace TestMemorySize
{
class MemoryInc
{
int _ManagedMemIncTimes = ;
int _UnmanagedMemIncTimes = ;
List<byte[]> _ManagedMemory = new List<byte[]>();
LinkedList<IntPtr> _UnmanagedMemory = new LinkedList<IntPtr>();
/// <summary>
/// Managed memory increase times
/// </summary>
public int ManagedMemIncTimes
{
get
{
return _ManagedMemIncTimes;
}
}
/// <summary>
/// Unmanaged memory increase times
/// </summary>
public int UnmanagedMemIncTimes
{
get
{
return _UnmanagedMemIncTimes;
}
}
/// <summary>
/// Increase managed memory
/// </summary>
public void IncManagedMemory()
{
_ManagedMemIncTimes++;
_ManagedMemory.Add(new byte[ * * _ManagedMemIncTimes]);
}
/// <summary>
/// Increase unmanaged memory
/// </summary>
public void IncUnmanagedMemory()
{
_UnmanagedMemIncTimes++;
_UnmanagedMemory.AddLast(Marshal.AllocCoTaskMem( * * _UnmanagedMemIncTimes));
}
}
}
MemoryLeakThread 这个线程没30秒增加1M的托管内存占用。
MemoryLeakThread
准备就绪,下面就开始体验了。
1、托管内存的跟踪
菜单中选择Profiler->Start 启动TestMemorySize.exe,然后输入m 并回车,这是分配了1M的托管内存。
在菜单中选择Profiler->Collect Heap Shapshot. 这是就可以看到堆中的所有对象了。
从这个界面我们看到虽然列出了对象的列表,但只有类型和大小等信息,却没有对象的名称以及分配过程
信息,这样怎么定位那块内存没有被释放啊?不要着急,.NET Memory Profiler还是比较强大的,让我们继续往下
前进。
双击选中的对象后进入对象所占用的堆的详细信息
再双击选中行,这时我们就可以看到对象的名称和分配堆栈的情况了。是不是很兴奋?终于找到是哪个家伙在捣蛋了。
2、线程中创建的托管内存的跟踪
线程中创建的托管内存跟踪方法和第1节介绍的方法基本是一样的。启动TestMemorySize.exe后输入t 并回车,创建一个
吃内存的线程。下面步骤都相同了。
3、非托管内存的跟踪
要跟踪非托管内存需要做一个设置:选择菜单中view->Project Property Pages,按下图进行设置。
设置好后启动TestMemorySize.exe后输入u 并回车,创建1M的非托管内存。下面步骤相同。
非托管内存无法看到对象的名称,但可以看到内存的申请过程,这对于定位内存问题已经提供了很大的帮助。
现在我们再输入m 回车,创建1M的托管内存,然后输入d 回车,这时我们可以发现memoryInc对象申请的托管内存已经被释放掉,
但非托管内存依然存在,内存在这里泄漏了!
这个工具还可以帮助我们计算出托管对象在堆中实际占用的内存大小,这也是一个很实用的功能,我们可以发现实际的占用大小
要比我们设计的大小略大,这是因为我们设计的类及其成员都是从一些基类中继承,这些基类的数据占用了一些内存造成。
到此如何跟踪基本.net应用的内存问题就介绍完毕。有时间再谢谢怎么跟踪ASP.NET应用的内存问题。
这一篇本来上午就要发出来,都快写完了,IE 崩溃!抓狂!
下午又重新写了一遍,郁闷啊。
用 .NET Memory Profiler 跟踪.net 应用内存使用情况--基本应用篇(转)的更多相关文章
- NET Memory Profiler 跟踪.net 应用内存
NET Memory Profiler 跟踪.net 应用内存 用 .NET Memory Profiler 跟踪.net 应用内存使用情况--基本应用篇 作者:肖波 .net 框架号称永远 ...
- Net Memory Profiler 分析.Net程序内存泄露
Net Memory Profiler 分析.Net程序内存泄露 Haozes's Tech Space 人類的全部才能無非是時間和耐心的混合物 使用.Net Memory Profiler 分析.N ...
- .NET Memory Profiler 查看内存使用情况
1 简介 .Net Memory Profiler(以下简称Profiler):专门针对于.NET程序,功能最全的内存分析工具,最大的特点是具有内存动态分析(Automatic Memory Anal ...
- 使用ANTS Performance Profiler&ANTS Memory Profiler工具分析IIS进程内存和CPU占用过高问题
一.前言 最近一段时间,网站经常出现两个问题: 1.内存占用率一点点增高,直到将服务器内存占满. 2.访问某个页面时,页面响应过慢,CPU居高不下. 初步判断内存一点点增多可能是因为有未释放的资源一直 ...
- [原创]推荐一款强大的.NET程序内存分析工具.NET Memory Profiler
[原创]推荐一款强大的.NET程序内存分析工具.NET Memory Profiler 1 官方网站:http://memprofiler.com/2 下载地址:http://memprofiler. ...
- Windbg + .Net .NET Memory Profiler 排查内存泄露
这是一个Winform程序,用于项目中的定时运算.症状是,运行一段时间后,内存持续上升.如一天内就能够达到300M. 打开.Net Memory Profiler,监控该程序,一段时间后,看到该程序产 ...
- (转).NET Memory Profiler 使用简介
1 简介 .Net Memory Profiler(以下简称Profiler):专门针对于.NET程序,功能最全的内存分析工具,最大的特点是具有内存动态分析(Automatic Mem ...
- MVC+MEF+UnitOfWork+EF架构,网站速度慢的原因总结!(附加ANTS Memory Profiler简单用法)
(最近使用内存分析工具ANTS Memory Profiler,以及其他网友提供的意见发现最终导致内存泄漏的就是MEF,在此特地更新下,与大家分享!最下面红色字体) 最近参考使用了郭明峰的一套架构来做 ...
- [转]ANTS Performance Profiler和ANTS Memory Profiler 使用
.NET性能调优之一:ANTS Performance Profiler的使用 .NET性能调优系列文章 系列文章索引 .NET性能调优之一:ANTS Performance Profiler的使 ...
随机推荐
- 分类器评估方法:ROC曲线
注:本文是人工智能研究网的学习笔记 ROC是什么 二元分类器(binary classifier)的分类结果 ROC空间 最好的预测模型在左上角,代表100%的灵敏度和0%的虚警率,被称为完美分类器. ...
- CF 494 F. Abbreviation(动态规划)
题目链接:[http://codeforces.com/contest/1003/problem/F] 题意:给出一个n字符串,这些字符串按顺序组成一个文本,字符串之间用空格隔开,文本的大小是字母+空 ...
- BZOJ.3522.[POI2014]Hotel(DP)
题目链接 BZOJ 洛谷 以为裸点分治,但数据范围怎么这么小?快打完了发现不对.. n^2做的话其实是个水题.. 枚举每一个点为根,为了不重复计算,我们要求所求的三个点必须分别位于三棵子树上. 考虑当 ...
- Shape流动效果
<Window x:Class="MvvmLight1.MainWindow" xmlns="http://schemas.microsoft.com/winfx/ ...
- 理解JVM模型
概括 JVM运行时数据区可以划分为5部分,分别是:程序计数器.虚拟机栈.本地方法栈.堆.方法区 程序计数器(Program Counter Register) 相当于当前线程所执行字节码的行号指示器. ...
- Android的设计尺寸
术语和概念 屏幕尺寸 指实际的物理尺寸,为屏幕对角线的测量.为了简单起见,Android把实际屏幕尺寸分为四个广义的大小:小,正常,大,特大. 像素(PX) 代表屏幕上一个物理的像素点代表屏幕上一个物 ...
- How to tell if a file is an EXE or a DLL?
How to tell if a file is an EXE or a DLL? void DumpFile(LPWSTR filename) { HANDLE hFile = CreateFile ...
- STM32的CRC32 软件实现代码
对于STM32的32位CRC,如果假定它的一个主要目的是为了校验往内部FLASH存储数据的可靠性,那么(余数)初值是全1当然是比较合理的.由于STM32的32位CRC是纯32位,即每次必须输入32位的 ...
- SQL 版本说明
http://www.cnblogs.com/SameZhao/p/6184924.html The ProductMajorVersion产品主版本号 如: 12为 SQL SERVER 2014 ...
- 用delphi实现完美屏幕截图
可以截取layered窗口(包括透明窗口)的代码: procedure CaptureScreen(AFileName: string);const CAPTUREBLT = $40000000;v ...