HttpClient的释放资源到底在释放什么?如何正确的释放资源?
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中需要释放的资源可以分为四种
内存,应用层用于发送请求或接收响应
底层Sokcet
Http连接,一个Http连接对应了一块用于收发数据的内存,同时绑定了一个socket。如下所示:
Http连接池
收发数据的内存跟socket是绑定在连接对象上的,所以如果我们正常关闭了连接,那么也就完成了对这两种资源的释放
Http连接池通常我们不会关闭,如果关闭了Http连接池意味着整个HttpClient对象不能再被使用
资源释放API介绍
我们常用的资源释放的API可以分为下面几类
HttpRequestBase对象的
releaseConnection
跟abort
方法,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
CloseableHttpResponse对象的
close
方法最终会调用
org.apache.http.impl.conn.PoolingHttpClientConnectionManager#releaseConnection
可以看到,当调用response对象的close方法,会关闭socket,同时释放连接到连接池。这里顺便说一下,连接的close方法跟shutdown方法的区别在于,close方法会尝试将未写完的数据全部写入server端,而shutdown会直接丢弃
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
,代码如下:可以看到,它只是简单的读取数据但没有进行其它任何操作,这实际是为了释放我们在前文提到了内存。这是为了安全的复用连接,我们需要将上次请求接收并缓存的所有数据清理干净,否则下次使用这个连接时可能读取到上次请求没有读取完的数据
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的释放资源到底在释放什么?如何正确的释放资源?相关推荐
- C#如何正确的释放资源
此标题可以为".NET 框架如何正确的释放资源".参考:https://www.cnblogs.com/fdyang/p/3456258.html 托管的内存资源,这是不需要我们操 ...
- HttpClient 如何正确的释放资源
HttpClient 需要关闭的资源 使用HttpClient 访问会涉及到三个层次的资源, 从上往下依次是: HttpClient 类型的对象.这是Http 呼叫的客户端. Http的请求的对象,一 ...
- mysql使用释放资源_数据库--释放mysql数据库资源
数据库--释放mysql数据库资源 背景 nikeodong 之前做了项目的数据库主从,在全备的过程发现数据库是越来越大了:最后发现是资源不释放的问题. 目的 为了解决 mysql 资源不释放的问题. ...
- java在退出前释放资源_Java中如何通过try优雅地释放资源?
1. 背景 其实,在JDK 7就已经引入了对 try-with-resources 的支持,它的主要作用就是解放小明和小明小伙伴们的双手,帮助我们自动释放使用过的资源(比如输入.输出流). 2. 例子 ...
- 到底怎样刷牙才是正确的?
注意事项 前牙舌腭侧如牙弓狭窄可将牙刷垂直,牙刷毛进入龈沟及邻间隙约45°角,对着牙长轴作短颤动.颌面的刷牙动作是将刷毛紧压颌面,使毛端深入点隙,作前后牙方向的颤动. 巴氏刷牙法刷牙的操作: 1.正确 ...
- 通过FD耗尽实验谈谈使用HttpClient的正确姿势
一段问题代码实验 在进行网络编程时,正确关闭资源是一件很重要的事.在高并发场景下,未正常关闭的资源数逐渐积累会导致系统资源耗尽,影响系统整体服务能力,但是这件重要的事情往往又容易被忽视.我们进行一个简 ...
- java httpclient cdn_通过FD耗尽实验谈谈使用HttpClient的正确姿势
一段问题代码实验 在进行网络编程时,正确关闭资源是一件很重要的事.在高并发场景下,未正常关闭的资源数逐渐积累会导致系统资源耗尽,影响系统整体服务能力,但是这件重要的事情往往又容易被忽视.我们进行一个简 ...
- C#资源释放及Dispose、Close和析构方法
C#资源释放及Dispose.Close和析构方法 备注:此文的部分观点有误,之所以仍旧保留本文,是需要在后期给出一个勘误版.正确的版本在这里"C#中标准Dispose模式的实现&quo ...
- 吐血总结:AQS到底是什么?
文章目录 1.概述 2.基本框架 2.1.AQS框架介绍 2.2.AQS核心成员变量和方法 3.源码分析 3.1.CLH队列(FIFO) 3.2.独占模式获取资源 3.2.1.acquire(int) ...
最新文章
- Hadoop实战(6)_搭建Apache Hadoop的Eclipse开发环境
- 读写EXCEL的例子
- 看完这篇文章你还敢说你懂JVM吗?
- centos 6.8安装git_CentOS7安装GitLab、汉化、邮箱配置及使用
- 团队作业4——第一次项目冲刺(Alpha版本)3rd day
- JAVA设计模式之装饰模式
- 张红英模型matlab,京师微课 | 北京市特级教师张红英:化学学科核心素养培养课例...
- Linux系统PATH变量配置
- C和指针之数组编程练习3(判断矩阵是否为单位矩阵)
- sed 第n行后加入_【高新课堂】第一百三十九期Liunx运维17个实用技巧
- jmeter java性能_jmeter之自定义java请求性能测试
- IOT---(8)四大物联网通信技术差异:NB-IoT 、LTEeMTC、LoRa与SigFox
- ELK和EFK的区别
- 这款老不死的笔记本,产品小姐姐的最爱......
- 如何使用给定的部分名称杀死所有进程?
- 那个爬虫框架好(简单对比)
- python归并排序算法实现_排序算法之归并排序(附 Python 与 JS 实现)
- 设计模式-行为性模式(模板方法模式,策略模式,命令模式,责任链模式,观察者模式,中介者模式,迭代器模式)
- 企业信息与网络通信安全 团队成员简历-叶俊
- 微信公众号实现“一键关注”功能
热门文章
- Need BLUETOOTH_PRIVILEGED permission
- “优化大师”出手,无线网络焕发新活力
- word用尾注插入参考文献—删除横线,空格等
- 近几年我在职场踩过的坑
- 信息系统项目管理师教程(第3版)- 结构化综合布线系统的组成特点
- 直驱永磁风机simulink仿真模型,内含网侧和机侧控制,低电压穿越控制(chopper电路控制),风速模拟,MPPT
- 视频安全之授权播放和防录屏跑马灯
- nest笔记七:参数校验
- python图片压缩pako_前端pako.js的 解压, json 转excel文件 下载
- WebMagic入门案例