代码编织梦想

背景

  某天在查询生产日志时,发现大量的Okhttp连接泄漏警告日志,但生产上没有收到任何异常反馈。出于好奇心,本地最小化复现问题,并最终解决问题。
在这里插入图片描述

分析问题

  1. okhttp官网的demo示例

    OkHttpClient client = new OkHttpClient();
    
    String run(String url) throws IOException {
      Request request = new Request.Builder()
          .url(url)
          .build();
    
      try (Response response = client.newCall(request).execute()) {
        return response.body().string();
      }
    }
    

    1.1 上述示例明显是Try-with-resources写法,最终会在finally里去关闭资源
    1.2 跟进string()源码发现最终也会关闭资源

  2. 分析官网示例,连接泄漏可能是因为执行请求没有关闭资源并且也没有执行string方法,导致资源始终没有关闭
    在这里插入图片描述
    2.1 上面示例在响应成功时就不会关闭连接资源

复现问题

  1. 启动一个简单服务端,暴露一个接口供客户端访问
    在这里插入图片描述
  2. 客户端请求
    在这里插入图片描述
    2.1 在执行请求时,会将调用者添加连接信息中(一个连接包含多个调用者),并且将调用者用虚引用包装
    在这里插入图片描述
    2.2 点进CallReference发现调用者用虚引用包装
    在这里插入图片描述
    2.3 在sendLocalhost方法执行完后,调用者引用关闭等待垃圾回收(当垃圾回收后,虚引用里的实际对象变为Null)
    (1)执行完sendLocalhost方法后打印断点,等待RealConnectionPool#pruneAndGetAllocationCount检查执行 在这里插入图片描述
    (2)在执行方法1的时候之前打上断点,通过System.gc()主动触发GC回收没有引用的调用者,这时reference.get()返回null,复现线上告警日志(为了让其触发垃圾回收,我把堆栈调的比较小)
    在这里插入图片描述
    在这里插入图片描述
    2.4 当连接的所有调用者都没有之后,进行连接驱逐释放

总结

  1. 搜索代码,将所有没有关闭资源的地方都进行关闭。后续发现再也没有相关警告日志出现了,成功解决问题
  2. 规范代码,调用请求和获取响应作为整体不进行拆分,然后将响应进行类型转换
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_40803011/article/details/127957712

android https、tls版本支持相关解决方案-爱代码爱编程

前言简介HTTPS相关 名词解释图解HTTPS协议加密解密全过程 异常解决 问题描述原因分析解决方案 参考链接 前言 在互联网安全通信方式上,目前用的最多的

android 开发的17个建议,紧跟google官方,进阶必看!_农家&子弟的博客-爱代码爱编程

摘要 使用 Gradle 和它推荐的工程结构把密码和敏感数据放在gradle.properties不要自己写 HTTP 客户端,使用Volley或OkHttp库使用Jackson库解析JSON数据避免使用Guava同时使用一些类库来避免65k method limit(一个Android程序中最多能执行65536个方法)使用 Fragments来呈现U

译文:android,okhttp and websockets_李诗雨的博客-爱代码爱编程

最近在看websocket的相关内容,参照的是我家豪哥的博客。所以本篇为转载! 【恩,就是这么臭buyao脸的称呼,希望不会被打哈】 原博客的出处:http://blog.csdn.net/xlh1191860939/

Android OkHttp-爱代码爱编程

目录 目录 前言 一.OkHttp整体架构 1.1.整体架构 1.2.Interface —— 接口层 1.2.1.OkHttpClient 1.2.2.Request 1.2.3.Call 1.2.4.Dispatcher 1.3.Protocol —— 协议层 1.4.Connection —— 连接层:管理网络连接,发送新的请求

猝死警告!熬夜2个月喜提26k字节安卓岗offer面经分享,非秃勿入!-爱代码爱编程

前言 从2020年11月开始面试准备到2020年最后一天31号晚上7点收到短信offer,历时两个月,在熬夜猝死边缘疯狂试探的我,终于等来我梦寐以求的“跨年礼物”。 “日尼玛,退钱”,《温暖的抱抱》电影前10分钟的开场剧情,让我不禁想着该如何说服朋友一起离场,却被自己短信铃声拉回了思绪,“应该调成静音的”。无聊的剧情本就让整个电影院变得十分寂静,赶紧把

干货分享!Android岗大厂面试官常问的那些问题,震撼来袭免费下载!-爱代码爱编程

谈起Android框架体系架构,我先提个问:什么是Android框架体系架构 ? Android系统构架是安卓系统的体系结构,android的系统架构和其操作系统一样,采用了分层的架构,共分为四层,从高到低分别是Android应用层,Android应用框架层,Android系统运行库层和Linux内核层。 Android系统构架主要应用于ARM平台,但

OkHttp源码解析-爱代码爱编程

一、OkHttp总体架构介绍 简介 OkHttp 是一个处理网络请求的开源项目,是 Android 端最火热的轻量级框架,由Square 公司贡献用于替代 HttpUrlConnection 和 Apache HttpClient。随着 OkHttp 的不断成熟,越来越多的 Android 开发者使用 OkHttp 作为网络框架。OkHttp之所以可以

Okhttp在页面结束的时候取消请求,防止内存泄漏-爱代码爱编程

 如果项目没有用mvp和mvvm这种框架自带解决网络请求内存泄漏,用的mvc处理内存泄漏的时候可以考虑rxjava解绑或直接取消okhttp的请求,下面这个方法就是直接取消okhttp的请求的方法 如果有tag并且tag是LifecycleOwner可以这样写 //tag直接用LifecycleOwner最方便 if (tag instanceof

Android源码解析------深入解析OkHttp源码-爱代码爱编程

深入解析OkHttp 源码 1 - OkHttp 3.7源码分析(一)——整体架构 简介: OkHttp是一个处理网络请求的开源项目,是Android端最火热的轻量级框架,由移动支付Square公司贡献用于替代HttpUrlConnection和Apache HttpClient。随着OkHttp的不断成熟,越来越多的Android开发者使用OkHtt

OkHttp 工具包 创建了太多 ConnectionPool 对象导致内存爆炸-爱代码爱编程

博文目录 文章目录 问题说明问题解决 问题说明 OkHttp ConnectionPool 对象居然有近2000个, 占用了太多的内存, 导致宕机 理论上讲, 既然都使用连接池了, 那连接池对象有1个应该就够了, 为什么这里会有近2000个? 原来是自己封装的 OkHttp 工具包的设计和使用上出了问题 该工具包支持传入 OkHttpCl

android面试基础二-爱代码爱编程

Android 面试基础一 目录 Android源码相关分析1、Android属性动画实现原理2、补间动画实现原理3、Android各个版本API的区别4、Requestlayout,onlayout,onD