最近遇到了这样一个问题,在Android开启StrictMode的时候,会抛出一个异常如下:

04-01 16:07:56.864: E/StrictMode(26867): A resource was acquired at attached stack trace but never released. See java.io.Closeable for information on avoiding resource leaks. 
04-01 16:07:56.864: E/StrictMode(26867): java.lang.Throwable: Explicit termination method 'close' not called
04-01 16:07:56.864: E/StrictMode(26867):         at dalvik.system.CloseGuard.open(CloseGuard.java:184) 
04-01 16:07:56.864: E/StrictMode(26867):         at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:271) 
04-01 16:07:56.864: E/StrictMode(26867):         at com.android.org.conscrypt.OpenSSLSocketImpl.waitForHandshake(OpenSSLSocketImpl.java:598) 
04-01 16:07:56.864: E/StrictMode(26867):         at com.android.org.conscrypt.OpenSSLSocketImpl.getInputStream(OpenSSLSocketImpl.java:560) 
04-01 16:07:56.864: E/StrictMode(26867):         at org.apache.http.impl.io.SocketInputBuffer.(SocketInputBuffer.java:70) 
04-01 16:07:56.864: E/StrictMode(26867):         at org.apache.http.impl.SocketHttpClientConnection.createSessionInputBuffer(SocketHttpClientConnection.java:83) 
04-01 16:07:56.864: E/StrictMode(26867):         at org.apache.http.impl.conn.DefaultClientConnection.createSessionInputBuffer(DefaultClientConnection.java:170) 
04-01 16:07:56.864: E/StrictMode(26867):         at org.apache.http.impl.SocketHttpClientConnection.bind(SocketHttpClientConnection.java:106) 
04-01 16:07:56.864: E/StrictMode(26867):         at org.apache.http.impl.conn.DefaultClientConnection.openCompleted(DefaultClientConnection.java:129) 
04-01 16:07:56.864: E/StrictMode(26867):         at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:172) 
04-01 16:07:56.864: E/StrictMode(26867):         at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164) 
04-01 16:07:56.864: E/StrictMode(26867):         at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119) 
04-01 16:07:56.864: E/StrictMode(26867):         at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:360) 
04-01 16:07:56.864: E/StrictMode(26867):         at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555) 
04-01 16:07:56.864: E/StrictMode(26867):         at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487) 
04-01 16:07:56.864: E/StrictMode(26867):         at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465)
异常大概是说资源没有释放,需要显示的调用close方法。从log上看是网络访问时出现的问题(我使用的是HttpClient)。
但是在关闭StrictMode的时候程序可以完全正常的运行。原因何在呢?
通过查看HttpClient官方文档发现,在HttpClient请求结束后需要销毁HttpEntity,这样才可以使网络连接返回连接池等待下一次重用(如果不需要重用的话也可以直接关掉连接)。
官方推荐的HttpEntity销毁方法:HttpEntity#consumeContent
在查看代码时发现,HttpEntity并没有销毁。可是其他网络请求部分的HttpEntity也都没有销毁,为什么只有这一个网络请求会报错呢?而且代码中有监听网络超时并关掉连接的处理,为什么还会出现这个问题呢?
仔细查看发现,出现问题的部分与其他部分稍有不同。出现问题的网络请求在解析响应的时候,并不需要解析Entity,他的响应结果是放在Headers里面的。也就是说这部分代码在请求结束的时候没有调用HttpResponse#getEntity#getContent方法。
查看HttpClient文档发现getContent方法也可以使Entity销毁。
所以就是这个原因使StrictMode抛出资源未释放的异常。
因为有了网络超时监听的处理,所以在关闭StrictMode的时候并不会出现什么问题,因为没有释放的连接会等到网络超时的时候会被释放。
在使用HttpClient时一定要注意资源的释放。即使有网络超时自动关闭连接的监听,StrictMode也会报告没有释放资源的异常,因为连接不会立即释放,需要等待超时时间的到来才会release,这样影响了程序的性能。
附HttpClient源码分析:
1.BasicHttpEntity#getContent源码:
在getContent方法中将contentObtained置为true;标记content已经被获取过了,在其他地方检测这个标记,如果资源被获取过,那么就会release掉这个连接。
2.BasicHttpEntity#consumeContent源码:
关闭content(content类型为InputStream)
3.EntityUtils#toString
在EntityUtils#toString方法的最后直接进行了reader.close();因此直接调用EntityUtils#toString方法后相当于调用了HttpEntity#consumeContent方法

转载于:https://www.cnblogs.com/younghome/p/4609022.html

HttpClient的释放问题相关推荐

  1. HttpClient 中文官方教程----第一章基础知识-只收录,未测试

    2019独角兽企业重金招聘Python工程师标准>>> 第一章基础知识 英文链接:http://hc.apache.org/httpcomponents-client-ga/tuto ...

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

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

  3. HttpClient API常用方法

    HttpClient API常用方法解释: 1.1 请求执行HttpClient最重要的功能是执行HTTP方法.执行HTTP方法涉及一个或多个HTTP请求/ HTTP响应交换,通常由HttpClien ...

  4. 如何解决 linux socket TIME_WAIT 过多造成的问题(SYN、ACK、FIN、MSL、RST含义)netstat查看TCP连接数命令

    文章目录 解决方法1 疑问:tcp_tw_reuse如何打开?要编译linux内核? 解决方法2:优化程序,减少TCP链接的创建与关闭,同一台服务器,连接一次就好了,不要连接了又关闭,然后再连接 相应 ...

  5. 搭建基于云端的中间层以支持跨平台的智能视觉服务

    不断演进的应用场景 初级应用场景-宅在家里 场景:Bob同学有一天在网上看到了一张建筑物的图片,大发感慨:"好漂亮啊!这是哪里?我要去亲眼看看!"Bob同学不想问别人,可笑的自尊心 ...

  6. DotNetCore动态库使用HttpClientFactory

    由于HttpClient有释放连接的问题,在DotNetCore使用HttpClient请求数据的话建议使用HttpClientFactory.但是网上清一色的都是针对Asp.NetCore的资料.都 ...

  7. Java 发送短信验证码

    Java 发送短信验证码给手机 发送短信验证码其实很简单,就是调用一下第三方的短信API接口,填写参数,发送请求,第三方平台会将信息发送给对方手机当中 介绍 我个人测试所使用的第三方API是" ...

  8. HttpClient-v4.5官方文档翻译

    HttpClient 4.5.2 前言 超文本传输协议(HTTP)可能是当今互联网上使用的最重要的协议.  网络服务,支持网络的设备以及网络计算的发展继续扩大了HTTP协议在用户驱动的Web浏览器之外 ...

  9. HttpClient的释放资源到底在释放什么?如何正确的释放资源?

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

最新文章

  1. Vitya and Strange Lesson (01字典树)
  2. 给新创建的用户 赋予所有的权利 *.* 查看权限 删除用户 ---------DCL用户权限管理篇...
  3. Citrix 服务器虚拟化之二十八 XenApp6.5发布文档内容
  4. webhook自定义服务器,GO 使用Webhook 实现github 自动化部署
  5. Fiddler抓取数据并分析(完整的配置教程)
  6. java 自动封装_自动补全的java封装
  7. 工作2年后悟出的道理
  8. 元素 float:right 后右对齐换行原因
  9. 网工协议基础(1) OSI七层模型
  10. com.netflix.zuul.exception.ZuulException: Hystrix Readed time out
  11. 【机器学习】正则化的线性回归 —— 岭回归与Lasso回归
  12. ANSYS——模态提取方法简介
  13. python 抽样函数_python中resample函数实现重采样和降采样代码
  14. spring boot使用Jedis整合Redis
  15. 计算机网络讨论课感悟,计算机网络课程学习心得体会
  16. Linux shell 脚本入门教程+实例
  17. jq 改数组的k值_在JSON jq中修改键值数组
  18. c语言公路竖曲线要素代码,竖曲线要素
  19. python 操作excel排序_python操作excel[转]
  20. CSDN 「Markdown」编辑器的优点、不足、使用技巧和新增功能|CSDN编辑器测评

热门文章

  1. C++Builder中开发Activex
  2. ubuntu10.04 android编译问题
  3. 移植2.6.38内核到s3c6410问题
  4. sjms-2 创建型模式
  5. 如何搭建服务器 无线传输,iOS 本地搭建服务器使用http传送(wifi快传)
  6. js map 排序_数组方法写给女友的一系列 JS 数组操作(建议收藏 | 内附思维导图)...
  7. centos 卸载docker_Spring Boot学习05_Docker卸载与安装
  8. 轻松处理高于平常10倍的视频需求,还能节省60%的IT成本,蓝墨做对了什么?
  9. 从微服务到 Serverless | 开源只是开始,终态远没有到来
  10. 实例比较虚幻引擎4与光线追踪渲染