Android复盘OkHttp HttpLoggingInterceptor造成的OOM
转载请标明出处: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复制的地方必定会经过,那么上面的问题就会出现。
解决办法:
方法一:就是定义两个
okhttp
(retrofit
也是两个)实例,一个专门用来下载文件,不加这个拦截器。另外一个专门添加这个拦截器去处理服务器返回数据。方法二:设置 level < Body
Android复盘OkHttp HttpLoggingInterceptor造成的OOM相关推荐
- Android 通过okhttp + jsoup 爬虫爬取网页小说
Android 通过okhttp + jsoup 爬虫爬取网页小说 效果图 1.准备工作 测试地址:http://www.tlxs.net 第三方依赖: implementation 'com.squ ...
- 【Android】OkHttp源码解读逐字稿(2)-OkHttpClient
目录 0.前言 1.各个属性浅析 01.dispatcher 02.connectionPool 03.interceptors&networkInterceptors 04.eventLis ...
- Android Studio OkHttp的使用
OkHttp的使用 总结一下,最近的学习OkHttp的过程中遇到的一列问题. 首先,要使用这个OkHttp之前需要添加OkHttp库的依赖.编辑app/build.gradle文件,在dependen ...
- android okhttpclient设置编码,Android之okhttp实现socket通讯(非原创)
文章大纲 一.okhttp基础介绍二.socket通讯代码实战三.项目源码下载四.参考文章 一.okhttp基础介绍 二.socket通讯代码实战 1. 添加依赖和权限 app的build.gradl ...
- Android Kotlin okhttp Retrofit 线程协程那些事
这篇文章不是用来讲概念的, 只是用来谈论一些关于Android 进程\协程那些问题 1. android 子线程中的异常会引发crash闪退吗? 答案是会的 Thread{throw RuntimeE ...
- 【Android之OkHttp介绍】
OkHttp是一个第三方类库,用于android中请求网络. 这是一个开源项目,是安卓端最火热的轻量级框架,由移动支付Square公司贡献(该公司还贡献了Picasso和LeakCanary) .用于 ...
- ZUI易入门Android之Okhttp的相关概念
什么是okhttp? okhttp是一个第三方类库,用于android中请求网络.这是一个开源项目,是安卓端最火热的轻量级框架,由移动支付Square公司贡献(该公司还贡献了Picasso和LeakC ...
- Android:OkHttp的理解和使用
OkHttp的理解和使用 OkHttp 1.什么是OkHttp 2.OkHttp的作用 3.Okhttp的基本使用 3.1.Http请求和响应的组成 3.2.OkHttp请求和响应的组成 3.3.GE ...
- Android开发解决加载图片OOM问题(非常全面 兼顾4 0以下系统)(by 星空武哥)
转载请标明:http://blog.csdn.net/lsyz0021/article/details/51295402 我们项目中经常会加载图片,有时候如果加载图片过多的话,小则导致程序很卡,重则O ...
最新文章
- HDU4920 Matrix multiplication 矩阵
- Best of Ruby Quiz 笔记之一:Mad Libs
- 在Windows上运行单节点的Cassandra
- 事务的隔离级别 mysql
- linux安装到内存中,Linux安装识别大内存的补丁程序
- 深度学习基础 | RNN家族全面解析
- 用MapX与C#开发地理信息系统
- 浅谈易用性测试及GUI常见的测试要求
- 思科计算机网络技术第一章,cisco思科网络技术教程第一章.ppt
- 简单无须Root 谷歌相机Gcam 打开即闪退的解决方法
- 程序猿 网站 | 常用 技术学习网站
- 7723java世界Ol,《世界OL》装备镶嵌
- “WORD上次启动失败,以安全模式启动”的解决方法
- 2019吉大软件C++课设——模拟即时通信系统
- python实验中遇到的问题及解决方法_Python中遇到的小问题及解决方法汇总
- EF Data Operation With Async Task
- 钢琴谱coda是什么意思
- leetcode,605题【种花问题】
- 2021 年使用 WordPress 作为 CMS 的 25 个热门网站
- 五、python实现人工蜂群算法(简单明了版)
热门文章
- 怎么在uefi解锁磁盘_系统重装时,如何秒判Windows启动是UEFI/Legacy?3步就够了!...
- php5.1 0day,DEDECMS 5.1 feedback_js.php 0DAY
- java读取ini_java 读取ini配置文件
- 按采用的传输介质计算机网络可分为4种,2015年4月全国自考计算机应用基础试卷及答案(00018)...
- Oracle的ha模式启停,数据库oracle 11g 的启停操作
- URI结构和ABNF操作符
- 【Python金融量化 1- 100 】三、流行股票指数
- 九十三、Python使用百度云接口API实现截图,文字识别和语音合成
- 二十三、Python队列实现多线程(下篇)
- 做时间序列预测有必要用深度学习吗?梯度提升回归树媲美甚至超越多个DNN模型...