- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
我有 10-150 个长寿类对象,它们调用使用 HttpClient 执行简单 HTTPS API 调用的方法。 PUT 调用示例:
using (HttpClientHandler handler = new HttpClientHandler())
{
handler.UseCookies = true;
handler.CookieContainer = _Cookies;
using (HttpClient client = new HttpClient(handler, true))
{
client.Timeout = new TimeSpan(0, 0, (int)(SettingsData.Values.ProxyTimeout * 1.5));
client.DefaultRequestHeaders.TryAddWithoutValidation("User-Agent", Statics.UserAgent);
try
{
using (StringContent sData = new StringContent(data, Encoding.UTF8, contentType))
using (HttpResponseMessage response = await client.PutAsync(url, sData))
{
using (var content = response.Content)
{
ret = await content.ReadAsStringAsync();
}
}
}
catch (ThreadAbortException)
{
throw;
}
catch (Exception ex)
{
LastErrorText = ex.Message;
}
}
}
在运行这些方法 2-3 小时后,其中包括通过 using
语句进行适当处理,程序的内存已攀升至 1GB-1.5GB,并最终因各种内存不足错误而崩溃。很多时候,连接是通过不可靠的代理进行的,因此连接可能无法按预期完成(超时和其他错误很常见)。
.NET Memory Profiler 指出 HttpClientHandler
是这里的主要问题,指出它同时具有“具有直接委托(delegate)根的已处置实例”(红色感叹号)和“已处置但尚未仍然没有 GCed'(黄色感叹号)。探查器指示已被 Root 的委托(delegate)是 AsyncCallback
,源自 HttpWebRequest。
它也可能与 RemoteCertValidationCallback
相关,这与 HTTPS 证书验证有关,因为 TlsStream
是根中更下方的一个对象,它是“Disposed but not GCed” '。
考虑到所有这些 - 我怎样才能更正确地使用 HttpClient 并避免这些内存问题?我应该每隔一小时左右强制执行一次 GC.Collect()
吗?我知道这被认为是不好的做法,但我不知道如何回收这个没有完全正确处理的内存,并且这些短期对象的更好使用模式对我来说并不明显,因为它似乎是 .NET 对象本身的缺陷。
更新强制 GC.Collect()
没有效果。
进程的总托管字节数最多保持在 20-30 MB 左右,而进程总内存(在任务管理器中)继续攀升,表明存在非托管内存泄漏。因此,这种使用模式会造成非托管内存泄漏。
我已尝试根据建议创建 HttpClient 和 HttpClientHandler 的类级别实例,但这没有明显的效果。即使我将这些设置为类级别,由于代理设置经常需要更改这一事实,它们仍然会重新创建并且很少重复使用。一旦发起请求,HttpClientHandler 不允许修改代理设置或任何属性,所以我不断地重新创建处理程序,就像最初使用独立的 using
语句所做的那样。
HttpClienthandler 仍然使用“直接委托(delegate)根”处理 AsyncCallback -> HttpWebRequest。我开始怀疑 HttpClient 是否不是为快速请求和短期对象而设计的。看不到尽头..希望有人建议使用 HttpClientHandler 可行。
内存分析器截图:
最佳答案
使用复制形式 Alexandr Nikitin,我发现这似乎仅在您将 HttpClient 设为短暂对象时才会发生。如果您使处理程序和客户端长寿,这似乎不会发生:
using System;
using System.Net.Http;
using System.Threading.Tasks;
namespace HttpClientMemoryLeak
{
using System.Net;
using System.Threading;
class Program
{
static HttpClientHandler handler = new HttpClientHandler();
private static HttpClient client = new HttpClient(handler);
public static async Task TestMethod()
{
try
{
using (var response = await client.PutAsync("http://localhost/any/url", null))
{
}
}
catch
{
}
}
static void Main(string[] args)
{
for (int i = 0; i < 1000000; i++)
{
Thread.Sleep(10);
TestMethod();
}
Console.WriteLine("Finished!");
Console.ReadKey();
}
}
}
关于c# - HttpClientHandler/HttpClient 内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27732546/
这是我得到的错误: Cannot initialize type 'HttpClientHandler' with a collection initializer because it does n
我需要将数据发送到需要证书授权的网络 API。但我不知道如何将证书添加到 .Net 4.5 中的处理程序。这是代码: // Import the certificate X509Certificate
我们有许多 .NET Core 2.1 服务和一些 .NET Framework 4.7.1 应用程序在客户的 Windows Server(我认为是 2016 年)机器上运行。客户设置了所有流量都需
我想使用 HttpClient 从我的 ViewModel 发送两个请求(首先是 GET,然后是 POST)。 GET 请求完成且没有任何错误。但是如果我发送 POST 请求我得到异常: {Syste
场景如下:用户使用证书身份验证连接到网络服务器,服务器正在调用其他服务,我想转发/发送我在服务器上收到的证书以通过服务对用户进行身份验证。 我在网络服务器上使用以下代码在 HttpClientHand
在 .net core 2.2(或更高版本)中,可以编写以下代码(在客户端)向启用了双向 TLS 身份验证的 REST 服务发送 json 请求并从中获取 json 响应: var clientHan
以下代码抛出“PlatformNotSupportedException”“此平台不支持操作” 它是一个 NET 标准库(尝试针对 1.4 和 2.0 进行编译),被作为 Web 应用程序运行的 .N
我有 10-150 个长寿类对象,它们调用使用 HttpClient 执行简单 HTTPS API 调用的方法。 PUT 调用示例: using (HttpClientHandler handler
当使用 HttpClient 实例和 HttpClientHandler 实例(.Net Framework,不使用 Core)时,是否可以稍后以任何方式访问 HttpClientHandler 实例
我目前正在配置我的 httpclientfactory这边走 HttpClientHandler httpClientHandler = new HttpClientHandler() { S
我有这个请求处理程序: var httpClientHandler = new HttpClientHandler { Proxy = new WebProxy(proxy.Address,
我想过用HttpClientFactory,但是调用的时候需要附上证书目前使用的是HttpClient,但是不知道怎么附上证书。 httpClient代码如下: HttpClientHandler h
我正在尝试将 Elasticsearch NEST 与 .NET Core 和我们的 Elasticsearch 实例结合使用。我们通过 SSL 连接,它有一个我们需要以编程方式接受的通配符证书。我想
我正在使用以下代码从使用 .Net Core 2.0 的 API 获取数据。 using (var handler = new HttpClientHandler() { Defaul
System.Net.Http.HttpClient和 System.Net.Http.HttpClientHandler在 .NET Framework 4.5 中实现 IDisposable(通过
在 中运行以下内容.NET 框架 4.7.2 控制台应用程序和 some_url指向我的 Windows 网络中使用 Kerberos 的服务器,我得到一个 HTTP 代码 200 背部: var h
我正在使用 Microsoft HTTP Client Libraries - PCL (通过 NuGet 安装)与公共(public) REST API 通信。因为我在公司防火墙后面,所以我需要在
我正在寻找 Mono HttpClient 堆栈的可移植替代品。可移植 Mono 版本 [常规 Mono 堆栈的一部分] 有错误。我一直在尝试修复影响我们项目的一个特定错误。由于异步操作所需的库的高度
我正在尝试使用 HTTP 客户端向网站发送表单。该网站然后根据我的请求返回一个包含数据的列表。该过程本身运行良好,但我必须执行 3 个请求,而当我在浏览器中手动执行时,一个请求就足够了。 在浏览器中,
代码如下: public static async Task DownloadPageWithCookiesAsync(string url) { HttpClientHandler hand
我是一名优秀的程序员,十分优秀!