ApacheHttpClient github地址:https://github.com/apache/httpcomponents-client/tree/4.5.x

ApacheHttpClient官网地址:https://hc.apache.org/httpcomponents-client-4.5.x/index.html

ApacheHttpClient介绍

本文主要想聊一聊ApacheHttpClient中资源释放的那些事,如果对它不够了解的话可以参考下面的思维导图:

链接:https://www.processon.com/view/link/641ef425fc0140496f0a3961

资源类型分类

在聊这个话题前我们先要明确HttpClient中定义的资源是什么,在HttpClient中需要释放的资源可以分为四种

  1. 内存,应用层用于发送请求或接收响应

  2. 底层Sokcet

  3. Http连接,一个Http连接对应了一块用于收发数据的内存,同时绑定了一个socket。如下所示:

  4. Http连接池

收发数据的内存跟socket是绑定在连接对象上的,所以如果我们正常关闭了连接,那么也就完成了对这两种资源的释放

Http连接池通常我们不会关闭,如果关闭了Http连接池意味着整个HttpClient对象不能再被使用

资源释放API介绍

我们常用的资源释放的API可以分为下面几类

  1. HttpRequestBase对象的releaseConnectionabort方法,HttpGet、HttpPost都继承了这个类。

    源码如下:

    这两个方法最终都会调用cancellableRef引用的对象的cancel方法,cancellableRef在不同的时机对应不同的资源对象:ConnectionRequest,代表一个从连接池中获取连接的请求。ConnectionHolder,代表一个真实的http连接

    代码位于:org.apache.http.impl.execchain.MainClientExec#execute

    当调用ConnectionRequest的cancel方法时,代表取消本次获取连接的请求。当调用ConnectionHolder的cancel方法时,代表什么呢?代码如下:org.apache.http.impl.execchain.ConnectionHolder#abortConnection

    上面代码主要做了两件事:关闭socket连接,归还连接到连接池。可能有的小伙伴会有疑问,为什么把连接绑定的socket关闭了还要将连接归还到连接池呢?这是因为连接池中的连接数量是有限制的,假设我们设置设置了最大连接数为10,如果不把这个连接归还到连接池,那么它会一直占用一个连接名额直到被驱逐策略所驱逐。并且在调用连接池的releaseConnection方法时,会判断归还的连接是否可用,如果不可用会直接从连接池中移除这个对象

    代码:org.apache.http.impl.conn.PoolingHttpClientConnectionManager#releaseConnection

  2. CloseableHttpResponse对象的close方法

    最终会调用org.apache.http.impl.conn.PoolingHttpClientConnectionManager#releaseConnection

    可以看到,当调用response对象的close方法,会关闭socket,同时释放连接到连接池。这里顺便说一下,连接的close方法跟shutdown方法的区别在于,close方法会尝试将未写完的数据全部写入server端,而shutdown会直接丢弃

  3. EntityUtils的consume方法跟toString方法以及关闭HttpEntity中的流

    EntityUtils的consume、toString最终都是调用HttpEntity.getContent().close方法,实际都是在关闭HttpEntity中的流

    最终会调用:org.apache.http.impl.execchain.ResponseEntityProxy#streamClosed

    wrapped.close()最终会调用org.apache.http.impl.io.ContentLengthInputStream#close,代码如下:

    可以看到,它只是简单的读取数据但没有进行其它任何操作,这实际是为了释放我们在前文提到了内存。这是为了安全的复用连接,我们需要将上次请求接收并缓存的所有数据清理干净,否则下次使用这个连接时可能读取到上次请求没有读取完的数据

  4. CloseableHttpClient对象的close方法

    这个方法会关闭所有HttpClient对象涉及的资源,包括连接池,HttpClient对象建议全局共享一个,因此一般不会调用

正确的释放资源

通过上面的分析,正确的资源释放姿势如下:

private static final CloseableHttpClient httpclient = HttpClients.createDefault();
public static void main(String[] args) throws Exception {try {HttpGet httpGet = new HttpGet("http://httpbin.org/get");CloseableHttpResponse response = httpclient.execute(httpGet);try {HttpEntity entity1 = response.getEntity();// 确保内存完成释放final String json = EntityUtils.toString(entity1);// 完成业务处理....}catch(){// 异常处理....} finally {// 保证连接释放,如果EntityUtils.toString调用成功,这个方法实际上不会做任何操作response.close();}}

HttpClient的释放资源到底在释放什么?如何正确的释放资源?相关推荐

  1. C#如何正确的释放资源

    此标题可以为".NET 框架如何正确的释放资源".参考:https://www.cnblogs.com/fdyang/p/3456258.html 托管的内存资源,这是不需要我们操 ...

  2. HttpClient 如何正确的释放资源

    HttpClient 需要关闭的资源 使用HttpClient 访问会涉及到三个层次的资源, 从上往下依次是: HttpClient 类型的对象.这是Http 呼叫的客户端. Http的请求的对象,一 ...

  3. mysql使用释放资源_数据库--释放mysql数据库资源

    数据库--释放mysql数据库资源 背景 nikeodong 之前做了项目的数据库主从,在全备的过程发现数据库是越来越大了:最后发现是资源不释放的问题. 目的 为了解决 mysql 资源不释放的问题. ...

  4. java在退出前释放资源_Java中如何通过try优雅地释放资源?

    1. 背景 其实,在JDK 7就已经引入了对 try-with-resources 的支持,它的主要作用就是解放小明和小明小伙伴们的双手,帮助我们自动释放使用过的资源(比如输入.输出流). 2. 例子 ...

  5. 到底怎样刷牙才是正确的?

    注意事项 前牙舌腭侧如牙弓狭窄可将牙刷垂直,牙刷毛进入龈沟及邻间隙约45°角,对着牙长轴作短颤动.颌面的刷牙动作是将刷毛紧压颌面,使毛端深入点隙,作前后牙方向的颤动. 巴氏刷牙法刷牙的操作: 1.正确 ...

  6. 通过FD耗尽实验谈谈使用HttpClient的正确姿势

    一段问题代码实验 在进行网络编程时,正确关闭资源是一件很重要的事.在高并发场景下,未正常关闭的资源数逐渐积累会导致系统资源耗尽,影响系统整体服务能力,但是这件重要的事情往往又容易被忽视.我们进行一个简 ...

  7. java httpclient cdn_通过FD耗尽实验谈谈使用HttpClient的正确姿势

    一段问题代码实验 在进行网络编程时,正确关闭资源是一件很重要的事.在高并发场景下,未正常关闭的资源数逐渐积累会导致系统资源耗尽,影响系统整体服务能力,但是这件重要的事情往往又容易被忽视.我们进行一个简 ...

  8. C#资源释放及Dispose、Close和析构方法

    C#资源释放及Dispose.Close和析构方法   备注:此文的部分观点有误,之所以仍旧保留本文,是需要在后期给出一个勘误版.正确的版本在这里"C#中标准Dispose模式的实现&quo ...

  9. 吐血总结:AQS到底是什么?

    文章目录 1.概述 2.基本框架 2.1.AQS框架介绍 2.2.AQS核心成员变量和方法 3.源码分析 3.1.CLH队列(FIFO) 3.2.独占模式获取资源 3.2.1.acquire(int) ...

最新文章

  1. Hadoop实战(6)_搭建Apache Hadoop的Eclipse开发环境
  2. 读写EXCEL的例子
  3. 看完这篇文章你还敢说你懂JVM吗?
  4. centos 6.8安装git_CentOS7安装GitLab、汉化、邮箱配置及使用
  5. 团队作业4——第一次项目冲刺(Alpha版本)3rd day
  6. JAVA设计模式之装饰模式
  7. 张红英模型matlab,京师微课 | 北京市特级教师张红英:化学学科核心素养培养课例...
  8. Linux系统PATH变量配置
  9. C和指针之数组编程练习3(判断矩阵是否为单位矩阵)
  10. sed 第n行后加入_【高新课堂】第一百三十九期Liunx运维17个实用技巧
  11. jmeter java性能_jmeter之自定义java请求性能测试
  12. IOT---(8)四大物联网通信技术差异:NB-IoT 、LTEeMTC、LoRa与SigFox
  13. ELK和EFK的区别
  14. 这款老不死的笔记本,产品小姐姐的最爱......
  15. 如何使用给定的部分名称杀死所有进程?
  16. 那个爬虫框架好(简单对比)
  17. python归并排序算法实现_排序算法之归并排序(附 Python 与 JS 实现)
  18. 设计模式-行为性模式(模板方法模式,策略模式,命令模式,责任链模式,观察者模式,中介者模式,迭代器模式)
  19. 企业信息与网络通信安全 团队成员简历-叶俊
  20. 微信公众号实现“一键关注”功能

热门文章

  1. Need BLUETOOTH_PRIVILEGED permission
  2. “优化大师”出手,无线网络焕发新活力
  3. word用尾注插入参考文献—删除横线,空格等
  4. 近几年我在职场踩过的坑
  5. 信息系统项目管理师教程(第3版)- 结构化综合布线系统的组成特点
  6. 直驱永磁风机simulink仿真模型,内含网侧和机侧控制,低电压穿越控制(chopper电路控制),风速模拟,MPPT
  7. 视频安全之授权播放和防录屏跑马灯
  8. nest笔记七:参数校验
  9. python图片压缩pako_前端pako.js的 解压, json 转excel文件 下载
  10. WebMagic入门案例