1

我有内存泄漏,仅在生产中发生(webapp(Asp.Net MVC))。

我想用 dotMemory(或类似的工具)拍摄内存快照,看看发生了什么。

但是我不确定这是否会导致生产暂停并弄乱当前的任何请求。

Fwiw 我的机器上有 32 GB 的 RAM

所以我的问题是:

我可以在不妨碍/影响请求的情况下获得内存快照吗?

4

1 回答 1

3

是的,dotMemory 和任何其他通过 Microsoft Profiling API 工作的内存分析器都会暂停应用程序一段时间,从几毫秒到几分钟不等,具体取决于内存中的数据量。

我建议使用标准的 Windows 内存转储,在正常情况下也需要一些时间,但有一种技术可以帮助避免它。然后您可以在 dotMemory 或任何其他支持 Windows 内存转储的工具中对其进行分析。

https://blogs.msdn.microsoft.com/granth/2012/07/02/how-to-take-a-memory-dump-of-an-asp-net-application-pool-quickly/

当我在 Microsoft 运行内部 Team Foundation Servers (TFS) 时,我们有时会遇到只能通过分析内存转储才能理解的问题。在运行 Beta 版之前的 Pioneer 和 Dogfood 服务器上尤其如此。如果问题足够严重(崩溃、内存泄漏等)以至于需要内存转储,这可能意味着它需要快速转储,以便我们可以回收应用程序池并让服务器恢复健康。

转储 ASP.NET 应用程序池的问题在于所有应用程序池都使用 w3wp.exe 进程名称。因此,在进行转储之前,您需要确定哪个进程对应于您的目标应用程序池。如果您无法通过查看进程所有者(例如服务帐户/应用程序池身份)来判断。简单(但缓慢)的方法是打开任务管理器并将“命令行”列添加到显示中。然后,您将在 w3wp.exe 进程的命令行中看到每个应用程序池名称。

消耗大量内存的应用程序池的另一个问题是,当内存转储到磁盘时,进程将暂停很长时间。如果这花费的时间比配置的 ASP.NET 进程“ping 时间”长,那么 IIS 将在转储的中途终止您的进程(并启动一个新进程),您将丢失您的复制。

为了解决这个问题,Sysinternals Procdump.exe 中提供了“-r”标志。它利用了 Windows 7/Windows 2008 R2 的一项功能,即“克隆”一个进程以进行转储,并以比正常速度更快的速度解除原始进程的挂起。

-r      Reflect (clone) the process for the dump to minimize the time 
        the process is suspended (Windows 7 and higher only).

然后我们可以使用 IIS 管理工具来查找特定应用程序池的进程 ID,现在我们有一个简单的批处理文件,我们可以将它放在 TFS 服务器的桌面上以便快速访问。

DumpTfsAppPool.cmd 创建以下批处理文件并将其放在与 Procdump.exe 相同的目录中。不要忘记创建/更新转储位置的路径。

%windir%\system32\inetsrv\appcmd list wps /apppool.name:"Microsoft
Team Foundation Server Application Pool" /text:WP.NAME >
"%temp%\tfspid.txt"


:: ProcDump.exe (faster, reflects/clones the process for the dump to
minimize the time the process is suspended (Windows 7 and higher
only))

for /F %%a in (%temp%\tfspid.txt) do "%~dp0\procdump.exe" -accepteula
-64 -ma -r %%a f:\dumps pause
于 2018-07-27T07:07:44.970 回答