转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/121903763
本文出自【赵彦军的博客】

文章目录

  • 前言
  • HttpLoggingInterceptor 简介
  • 下载文件请求阶段需要等很久以及OOM

前言

最近项目中发生了很多 oom,通过 oom 日志分析来看,都跟 okhttp 有关。经过艰难的分析定位,终于发现了造成 oom 的凶手HttpLoggingInterceptor

原因是 HttpLoggingInterceptor 作为 okhttp 请求的过程的日志输出工具, 会把 ResponseBody 里面内容全部读出来,放在内存里。对于普通的网络请求,影响并不大。但是对于下载来说,它会把整个文件读出来,放在内存,就非常容易造成 oom

HttpLoggingInterceptor 简介

该拦截器用于记录应用中的网络请求的信息。

使用:

val okHttpClientBuilder: OkHttpClient.Builder = OkHttpClient.Builder()//创建日志拦截器
val logging = HttpLoggingInterceptor { message -> UtilLog.v("OkHttp", message) }
logging.level = HttpLoggingInterceptor.Level.BODY//添加日志拦截器
okHttpClientBuilder.addInterceptor(logging)

日志包含4个等级,含四个级别:NONE、BASIC、HEADER、BODY

NONE 不记录BASIC 请求/响应行
--> POST /greeting HTTP/1.1 (3-byte body)
<-- HTTP/1.1 200 OK (22ms, 6-byte body)HEADER 请求/响应行 + 头
--> Host: example.com
Content-Type: plain/text
Content-Length: 3
<-- HTTP/1.1 200 OK (22ms)
Content-Type: plain/text
Content-Length: 6BODY 请求/响应行 + 头 + 体

下载文件请求阶段需要等很久以及OOM

正常请求没什么问题,但是当我使用这个 okhttp 实例去下载文件的时候出现了问题,请求很久才能拿到正文开始下载。

开始我以为是链接的问题,换了之后发现还是这样,经过一番定位(一行行注释),把问题定位到了HttpLoggingInterceptor拦截器上,发现添加了这个拦截器,并且把level设置为Body的时候就会出现这种情况(由于android不允许在主线程请求网络,所以UI没卡),之后经过调试,发现当代码走到以下位置时,就会卡住。


大致原因应该是这里需要将内容全部请求出来。

然而在你下载东西的时候,内容是很多的,那么这里的卡住的时长和文件大小成正比,如果文件太大,内存不够,那么系统会不停地GC去获取更多内存,但是总内存就那么点大,所以这就是个死结,甚至会OOM

当然,这里设置level < Body就好了,但是有些时候会有特殊需求,比如说新加一个拦截器,需要根据服务端返回的数据做不同的处理,这里就要参照 HttpLoggingInterceptor 自定义一个拦截器,buffer复制的地方必定会经过,那么上面的问题就会出现。

解决办法:

  • 方法一:就是定义两个 okhttpretrofit也是两个)实例,一个专门用来下载文件,不加这个拦截器。另外一个专门添加这个拦截器去处理服务器返回数据。

  • 方法二:设置 level < Body

Android复盘OkHttp HttpLoggingInterceptor造成的OOM相关推荐

  1. Android 通过okhttp + jsoup 爬虫爬取网页小说

    Android 通过okhttp + jsoup 爬虫爬取网页小说 效果图 1.准备工作 测试地址:http://www.tlxs.net 第三方依赖: implementation 'com.squ ...

  2. 【Android】OkHttp源码解读逐字稿(2)-OkHttpClient

    目录 0.前言 1.各个属性浅析 01.dispatcher 02.connectionPool 03.interceptors&networkInterceptors 04.eventLis ...

  3. Android Studio OkHttp的使用

    OkHttp的使用 总结一下,最近的学习OkHttp的过程中遇到的一列问题. 首先,要使用这个OkHttp之前需要添加OkHttp库的依赖.编辑app/build.gradle文件,在dependen ...

  4. android okhttpclient设置编码,Android之okhttp实现socket通讯(非原创)

    文章大纲 一.okhttp基础介绍二.socket通讯代码实战三.项目源码下载四.参考文章 一.okhttp基础介绍 二.socket通讯代码实战 1. 添加依赖和权限 app的build.gradl ...

  5. Android Kotlin okhttp Retrofit 线程协程那些事

    这篇文章不是用来讲概念的, 只是用来谈论一些关于Android 进程\协程那些问题 1. android 子线程中的异常会引发crash闪退吗? 答案是会的 Thread{throw RuntimeE ...

  6. 【Android之OkHttp介绍】

    OkHttp是一个第三方类库,用于android中请求网络. 这是一个开源项目,是安卓端最火热的轻量级框架,由移动支付Square公司贡献(该公司还贡献了Picasso和LeakCanary) .用于 ...

  7. ZUI易入门Android之Okhttp的相关概念

    什么是okhttp? okhttp是一个第三方类库,用于android中请求网络.这是一个开源项目,是安卓端最火热的轻量级框架,由移动支付Square公司贡献(该公司还贡献了Picasso和LeakC ...

  8. Android:OkHttp的理解和使用

    OkHttp的理解和使用 OkHttp 1.什么是OkHttp 2.OkHttp的作用 3.Okhttp的基本使用 3.1.Http请求和响应的组成 3.2.OkHttp请求和响应的组成 3.3.GE ...

  9. Android开发解决加载图片OOM问题(非常全面 兼顾4 0以下系统)(by 星空武哥)

    转载请标明:http://blog.csdn.net/lsyz0021/article/details/51295402 我们项目中经常会加载图片,有时候如果加载图片过多的话,小则导致程序很卡,重则O ...

最新文章

  1. HDU4920 Matrix multiplication 矩阵
  2. Best of Ruby Quiz 笔记之一:Mad Libs
  3. 在Windows上运行单节点的Cassandra
  4. 事务的隔离级别 mysql
  5. linux安装到内存中,Linux安装识别大内存的补丁程序
  6. 深度学习基础 | RNN家族全面解析
  7. 用MapX与C#开发地理信息系统
  8. 浅谈易用性测试及GUI常见的测试要求
  9. 思科计算机网络技术第一章,cisco思科网络技术教程第一章.ppt
  10. 简单无须Root 谷歌相机Gcam 打开即闪退的解决方法
  11. 程序猿 网站 | 常用 技术学习网站
  12. 7723java世界Ol,《世界OL》装备镶嵌
  13. “WORD上次启动失败,以安全模式启动”的解决方法
  14. 2019吉大软件C++课设——模拟即时通信系统
  15. python实验中遇到的问题及解决方法_Python中遇到的小问题及解决方法汇总
  16. EF Data Operation With Async Task
  17. 钢琴谱coda是什么意思
  18. leetcode,605题【种花问题】
  19. 2021 年使用 WordPress 作为 CMS 的 25 个热门网站
  20. 五、python实现人工蜂群算法(简单明了版)

热门文章

  1. 怎么在uefi解锁磁盘_系统重装时,如何秒判Windows启动是UEFI/Legacy?3步就够了!...
  2. php5.1 0day,DEDECMS 5.1 feedback_js.php 0DAY
  3. java读取ini_java 读取ini配置文件
  4. 按采用的传输介质计算机网络可分为4种,2015年4月全国自考计算机应用基础试卷及答案(00018)...
  5. Oracle的ha模式启停,数据库oracle 11g 的启停操作
  6. URI结构和ABNF操作符
  7. 【Python金融量化 1- 100 】三、流行股票指数
  8. 九十三、Python使用百度云接口API实现截图,文字识别和语音合成
  9. 二十三、Python队列实现多线程(下篇)
  10. 做时间序列预测有必要用深度学习吗?梯度提升回归树媲美甚至超越多个DNN模型...