热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

HttpClientHandler/HttpClient内存泄漏

如何解决《HttpClientHandler/HttpClient内存泄漏》经验,为你挑选了1个好方法。

我有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是主要的问题,声明它既有"具有直接委托根的Disposed实例"(红色感叹号)和"已经处置但仍未进行GC处理的实例"(黄色感叹号).探查器指示已经根植的代表是AsyncCallbacks,源自HttpWebRequest.

它还可能RemoteCertValidationCallback与HTTPS证书验证有关,因为它TlsStream是根目录中的"Disposed但not not GCed".

考虑到这一切 - 我怎样才能更正确地使用HttpClient并避免这些内存问题?我应该GC.Collect()每小时强迫一次吗?我知道这被认为是不好的做法,但我不知道如何回收这个不太适当处理的内存,并且这些短命对象的更好的使用模式对我来说并不明显,因为它似乎是.NET对象本身的一个缺陷.


更新 强制GC.Collect()没有效果.

进程的总管理字节数最多保持在20-30 MB左右,而进程总内存(在任务管理器中)继续爬升,表明存在非托管内存泄漏.因此,此使用模式正在创建非托管内存泄漏.

我已经尝试根据建议创建HttpClient和HttpClientHandler的类级别实例,但这没有明显的效果.即使我将这些设置为类级别,它们仍然会重新创建并且很少重复使用,因为代理设置通常需要更改.一旦请求启动,HttpClientHandler就不允许修改代理设置或任何属性,因此我不断重新创建处理程序,就像最初使用独立using语句一样.

HttpClienthandler仍然使用"直接委托根"来处理AsyncCallback - > HttpWebRequest.我开始想知道HttpClient是否可能不是为快速请求和短生命对象而设计的.没有尽头......希望有人建议使用HttpClientHandler可行.


记忆探测器镜头: 初始堆栈指示HttpClientHandler是根本问题,具有应该已经GC的304个实时实例

在此输入图像描述

在此输入图像描述



1> 小智..:

使用repr形式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();
        }
    }
}


感谢您深究这一点.不幸的是,HttpClient类不符合我的要求 - 由于公共代理的动态和不稳定性,通常需要重新创建对象.看来HttpClient对于短生命连接来说不是一个可行的解决方案 - 更改代理设置需要重新构建HttpClientHandler,从而重新构建HttpClient.无论哪种方式,物体应该能够在不泄漏的情况下根据需要长寿或短缺; 这肯定是HttpClient中的一个缺陷.
推荐阅读
  • 本文探讨了在使用Apache Flink向Kafka发送数据过程中遇到的事务频繁失败问题,并提供了详细的解决方案,包括必要的配置调整和最佳实践。 ... [详细]
  • 本文详细介绍了如何利用go-zero框架从需求分析到最终部署至Kubernetes的全过程,特别聚焦于微服务架构中的网关设计与实现。项目采用了go-zero及其生态组件,涵盖了从API设计到RPC调用,再到生产环境下的监控与维护等多方面内容。 ... [详细]
  • 本文探讨了在使用 ClickOnce 部署方式时遇到的自动更新失败问题,包括本地安装与服务器安装的不同表现,并提供了详细的解决方案。 ... [详细]
  • C#爬虫Fiddler插件开发自动生成代码
    哈喽^_^一般我们在编写网页爬虫的时候经常会使用到Fiddler这个工具来分析http包,而且通常并不是分析一个包就够了的,所以为了把更多的时间放在分析http包上,自动化生成 ... [详细]
  • 解决宝塔面板Nginx反向代理缓存问题
    本文介绍如何在宝塔控制面板中通过编辑Nginx配置文件来解决反向代理中的缓存问题,确保每次请求都能从服务器获取最新的数据。 ... [详细]
  • 提升接口测试效率的关键:用例与工具的综合应用
    本文将探讨如何通过有效的接口测试用例设计和工具选择,显著提高接口测试的效率和质量。 ... [详细]
  • Web网络基础
    目录儿1使用HTTP协议访问Web2HTTP的诞生2.1因特网的起源2.2互联网、因特网与万维网2.3万维网与HTTP3网络基础TCPIP3.1TCPIP协议族3.2TCPIP的分 ... [详细]
  • VSCode中实现大型项目函数跳转的方法
    在处理大型代码项目时,简单的C/C++插件往往无法满足需求。本文介绍如何通过配置GNU Global等工具,在VSCode中实现高效的函数跳转。 ... [详细]
  • 我们正在使用GNU Make来构建我们的系统,在makefile文件的末尾,我们通过一个名为Makedepends的包含来生成一系列的.d文件。然而,当文件被删除或移动时,依赖关系会中断,我们需要寻找一种方法来优雅地处理这种情况。 ... [详细]
  • 本文详细介绍了如何在Linux系统上安装和配置单节点的Redis服务,包括下载、解压、编译安装以及启动服务的具体步骤。 ... [详细]
  • Cadence SPB 16.5 安装指南与注意事项
    本文提供了详细的 Cadence SPB 16.5 安装步骤,包括环境配置、安装过程中的关键步骤以及常见问题的解决方案。适合初次安装或遇到问题的技术人员参考。 ... [详细]
  • 字符、字符串和文本的处理之Char类型
    .NetFramework中处理字符和字符串的主要有以下这么几个类:(1)、System.Char类一基础字符串处理类(2)、System.String类一处理不可变的字符串(一经 ... [详细]
  • C# 线程状态判断与委托使用
    本文探讨了C#中线程状态的判断方法及委托的使用技巧,深入分析了ThreadState枚举的特性及其在多线程编程中的应用。 ... [详细]
  • 本文详细解析了Java中流的概念,特别是OutputStream和InputStream的区别,并通过实际案例介绍了如何实现Java对象的序列化。文章不仅解释了流的基本概念,还探讨了序列化的重要性和具体实现步骤。 ... [详细]
  • 探讨了生成时间敏感的一次性伪随机密码的方法,旨在通过加入时间因素防止重放攻击。 ... [详细]
author-avatar
dashan
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有