【发布时间】:2019-04-25 03:45:54
【问题描述】:
我一直在尝试追踪(似乎是)在 Azure 中运行的 ASP.NET Core 应用程序中的内存泄漏。我在应用程序启动时收集了一个 DMP,并在内存达到峰值时收集了一个 DMP,然后就停止了并崩溃。我正在尝试使用 PerfView 破译 DMP 文件。我加载了第一个转储,然后是第二个并做了一个差异。 “按名称”选项卡的输出如下所示:
所以,问题一是:我读对了吗?这是否告诉我有 18,501 个 HttpClient 实例?如果是这样,天哪。
我进入了“RefTree”选项卡,这是我在那里看到的: 果然,似乎占据大部分的 HttpClient 来自我的图书馆 LGAuthLib。
所以,我不明白的是,HttpClient 是一个静态对象,在该类库的静态构造函数中分配一次,然后在任何地方使用。怎么可能分配 18,000 个呢?可以存在 18,000 个容纳静态对象的类库吗?我不知道这怎么可能,因为该对象是在 DI 单例中分配的。
这就是为什么我不能 100% 确定我是否正确阅读了这个差异。我只是想不通这怎么可能泄漏。
对于那些盯着这些东西的专业人士,您是否 100% 确定 HttpClient 对象正在泄漏?
为了完整起见,这里是我使用 HttpClient 对象的方式:
public async Task<string[]> GetRolesForUserByUserNameAsync(string strUser)
{
var reqParams = new HttpRequestMessage(HttpMethod.Post, new UriBuilder(_config.ServerUri)
{
Path = EndpointGetRolesForUserByMicroService
}.Uri);
reqParams.Headers.Add("MicroService", CreateMicroServiceHeaderValue(EndpointGetRolesForUserByMicroService));
reqParams.Content = HttpClientExtensions.JsonContent(new { userName = strUser });
using (var resp = await _httpClient.SendAsync(reqParams).ConfigureAwait(false))
{
resp.EnsureSuccessStatusCode();
return (await resp.Content.ReadAsJsonAsync<string>().ConfigureAwait(false)).Split(',');
}
}
这是它的分配方式:
public sealed class AuthService
{
private static readonly HttpClient _httpClient;
static AuthService()
{
_httpClient = new HttpClient();
}
}
【问题讨论】:
-
您如何使用它并不重要。如果有 18K 实例,我们需要查看它是如何创建的。
-
已更新。我想也许不处理
HttpRequestMessage可能会导致一些问题,所以这就是我添加的原因 -
如果我正确地看到了那些 tiny 图像,我认为您正在查看的是包容性和排他性样本数。任何类型的分析器都使用采样进行分析,无论是 CPU 周期还是堆分配。你能澄清一下是什么让你认为你有内存泄漏吗?
-
您可以点击图片,它应该会显示完整尺寸。我不确定是否代表内存泄漏。这就是我的问题——可以从 PerfView 中获取哪些信息?
-
A LOT,实在是太多了,无法在此一一解释。如果我没记错的话,几乎没有“?”用于解释列信息的链接。
标签: c# asp.net-core memory-leaks .net-core