当前位置: 首页 > news >正文

【Android】一个contentResolver引起的内存泄漏问题分析

长时间的压力测试后,系统发生了重启,报错log如下

JNI ERROR (app bug): global reference table overflow (max=51200)

global reference table overflow的log

08-08 04:11:53.052912   973  3243 F zygote64: indirect_reference_table.cc:256] JNI ERROR (app bug): global reference table overflow (max=51200)

08-08 04:11:53.053014   973  3243 F zygote64: indirect_reference_table.cc:256] global reference table dump:

08-08 04:11:53.053172   973  3243 F zygote64: indirect_reference_table.cc:256]   Summary:

08-08 04:11:53.053184   973  3243 F zygote64: indirect_reference_table.cc:256]     27087 of com.android.server.content.ContentService$ObserverNode$ObserverEntry (27087 unique instances)

08-08 04:11:53.053197   973  3243 F zygote64: indirect_reference_table.cc:256]     22849 of java.lang.ref.WeakReference (22849 unique instances)

08-08 04:11:53.053210   973  3243 F zygote64: indirect_reference_table.cc:256]       313 of java.lang.Class (235 unique instances)

Backtrace:

    #00 pc 000000000001d754  /system/lib64/libc.so (abort+120)

    #01 pc 00000000004766f0  /system/lib64/libart.so (art::Runtime::Abort(char const*)+552)

    #02 pc 000000000056c5ec  /system/lib64/libart.so (android::base::LogMessage::~LogMessage()+1004)

    #03 pc 0000000000264304  /system/lib64/libart.so (art::IndirectReferenceTable::Add(art::IRTSegmentState, art::ObjPtr<art::mirror::Object>)+764)

    #04 pc 00000000002ff7fc  /system/lib64/libart.so (art::JavaVMExt::AddGlobalRef(art::Thread*, art::ObjPtr<art::mirror::Object>)+68)

    #05 pc 0000000000343834  /system/lib64/libart.so (art::JNI::NewGlobalRef(_JNIEnv*, _jobject*)+572)

    #06 pc 000000000011fe5c  /system/lib64/libandroid_runtime.so (JavaDeathRecipient::JavaDeathRecipient(_JNIEnv*, _jobject*, android::sp<DeathRecipientList> const&)+136)

    #07 pc 000000000011f9a4  /system/lib64/libandroid_runtime.so (android_os_BinderProxy_linkToDeath(_JNIEnv*, _jobject*, _jobject*, int)+224)

根据经验,又是binder的溢出,因为在生成BinderProxy对象的时候,调用到了jobject javaObjectForIBinder方法,里面进行了NewGlobalRef操作

vi frameworks/base/core/jni/android_util_Binder.cpp

547 jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val)

 548 {

 549     if (val == NULL) return NULL;

585         jobject refObject = env->NewGlobalRef(

 586                 env->GetObjectField(object, gBinderProxyOffsets.mSelf));

 587         val->attachObject(&gBinderProxyOffsets, refObject,

 588                 jnienv_to_javavm(env), proxy_cleanup);

如果太多的BinderProxy对象没有释放,就会导致global reference table overflow。

我们使用dumpsys meminfo <system_server_PID>

来进行查看验证

ps -ef|grep system_s

system         820   480 1 18:05:55 ?     01:47:51 system_server

得到system_server的进程号为820

dumpsys meminfo 820

               Views:        9         ViewRootImpl:        2

         AppContexts:       25           Activities:        0

              Assets:       11        AssetManagers:       13

       Local Binders:      401        Proxy Binders:    16509

       Parcel memory:      288         Parcel count:      249

    Death Recipients:    15939      OpenSSL Sockets:        0

可以看到Proxy Binders非常多

我们可以在Binder的构造以及析构方法中添加log来观察是哪里new了太多的对象。

我们可以使用 dumpsys meminfo <PID> 命令逐个查看是哪个进程里new了过多的Local Binders来进行排查。

在这个例子中,我们查看到log中有

08-08 04:11:53.053172   973  3243 F zygote64: indirect_reference_table.cc:256]   Summary:

08-08 04:11:53.053184   973  3243 F zygote64: indirect_reference_table.cc:256]     27087 of com.android.server.content.ContentService$ObserverNode$ObserverEntry (27087 unique instances)

08-08 04:11:53.053197   973  3243 F zygote64: indirect_reference_table.cc:256]     22849 of java.lang.ref.WeakReference (22849 unique instances)

08-08 04:11:53.053210   973  3243 F zygote64: indirect_reference_table.cc:256]       313 of java.lang.Class (235 unique instances)

ContentService$ObserverNode$ObserverEntry的泄漏较多,

对于ContentService,刚好可以使用命令 dumpsys content来进行查看

我们发现里面有上万个

  settings/global/always_on_display_constants: pid=10928 uid=10027 user=-1 target=6497568

  settings/global/always_on_display_constants: pid=10928 uid=10027 user=-1 target=57cdd81

pid=10928 是systemui

Unknown:/ # ps -ef|grep systemui

u0_a27       10928   480 0 18:20:02 ?     00:38:59 com.android.systemui

再来验证下

dumpsys meminfo 10928

       Local Binders:    15629        Proxy Binders:       67

       Parcel memory:       22         Parcel count:       83

    Death Recipients:        2      OpenSSL Sockets:        0

再根据always_on_display_constants进行查找,就找到了注册Observer的地方了。

就定位到泄漏点了。

相关文章:

【Android】一个contentResolver引起的内存泄漏问题分析

长时间的压力测试后&#xff0c;系统发生了重启&#xff0c;报错log如下 JNI ERROR (app bug): global reference table overflow (max51200) global reference table overflow的log 08-08 04:11:53.052912 973 3243 F zygote64: indirect_reference_table.cc:256] JNI ER…...

2023年正版win10/win11系统安装教学(纯净版)

第一步&#xff1a;准备一个8G容量以上的U盘。 注意&#xff0c;在制作系统盘时会格式化U盘&#xff0c;所以最好准备个空U盘&#xff0c;防止资料丢失。 第二步&#xff1a;制作系统盘。 安装win10 进入windows官网 官网win10下载地址&#xff1a;https://www.microsoft.c…...

系统架构设计师-第11章-未来信息综合技术-软考学习笔记

未来信息综合技术是指近年来新技术发展而提出的一些新概念、新知识、新产品 信息物理系统(CPS ) &#xff0c;人工智能( A l) &#xff0c;机器人、边缘计算、数字孪生、云计算和大数据等技术 信息物理系统技术概述 信息物理系统的概念 信息物理系统是控制系统、嵌入式系统…...

Python __new__()方法详解

__new__() 是一种负责创建类实例的静态方法&#xff0c;它无需使用 staticmethod 装饰器修饰&#xff0c;且该方法会优先 __init__() 初始化方法被调用。 一般情况下&#xff0c;覆写 __new__() 的实现将会使用合适的参数调用其超类的 super().__new__()&#xff0c;并在返回之…...

虹科 | 解决方案 | 汽车示波器 索赔管理方案

索赔管理 Pico汽车示波器应用于主机厂/供应商与服务店/4S店的协作&#xff0c;实现产品索赔工作的高效管理&#xff1b;同时收集的故障波形数据&#xff0c;便于日后的产品优化和改进 故障记录 在索赔申请过程中&#xff0c;Pico汽车示波器的数据记录功能可以用于捕捉故障时的…...

详解Jmeter中的BeanShell脚本

BeanShell是一种完全符合Java语法规范的脚本语言,并且又拥有自己的一些语法和方法&#xff0c;所以它和java是可以无缝衔接的&#xff0c;学了Java的一些基本语法后&#xff0c;就可以来在Jmeter中写写BeanShell脚本了 在利用jmeter进行接口测试或者性能测试的时候&#xff0c…...

前端和后端 优化

1.前端资源优化 1.1 html结构优化 保证简洁、清晰的html结构&#xff0c;减少或避免多余的html标签 使用HTML5的web语义化标签&#xff0c;结构清晰且利于seo css文件在head中引入&#xff0c;js文件放在body底部引入&#xff0c;这样做可以防止阻塞。另外如果有需要提前加载的…...

C++编译与运行:其二、编译期和运行期的区别

C的编译分为四步&#xff0c;最终生成一个可执行文件。 C的运行&#xff0c;就是将可执行文件交给操作系统&#xff0c;按照机器码逐步执行&#xff0c;运行功能。 先看一个非常非常有趣的例子&#xff1a; class Father{ public:virtual void f(){cout<<"I am fat…...

汽车电子专有名词与相应技术

1.EEA &#xff08;Electronic & Electrical Architecture 电子电气架构&#xff09; EEA在宏观上概括为物理架构与逻辑架构的结合&#xff0c;微观上通过众多电子元器件的协同配合&#xff0c;或集成式或分布式的系统级电子电气架构&#xff0c;具体详见专栏 新能源汽车电…...

idea 没加载 provided的包

目录 前言解决方案 前言 我的版本是IntelliJ IDEA 2022.1.4 (Community Edition)&#xff0c;本地调试不知道为什么不加载provided的包。后来找到这篇文章https://youtrack.jetbrains.com/issue/IDEA-107048才知道这是个bug。不知道其他版本会不会出现这种问题。 解决方案 我…...

Hover:借贷新势力崛起,在经验与创新中找寻平衡

复苏中的Cosmos 如果让我选择一个最我感到可惜的区块链项目&#xff0c;我会选择Cosmos。 Cosmos最早提出并推动万链互联的概念&#xff0c;希望打通不同链之间的孤岛&#xff0c;彼时和另一个天王项目Polkadot号称跨链双雄。其跨链技术允许不同的区块链网络互相通信&#xf…...

软件设计原则-依赖倒置原则讲解以及代码示例

依赖倒置原则 一&#xff0c;介绍 1.前言 依赖倒置原则&#xff08;Dependency Inversion Principle&#xff0c;DIP&#xff09;是面向对象设计中的一个重要原则&#xff0c;由Robert C. Martin提出。 依赖倒置原则的核心思想是&#xff1a;高层模块不应该依赖于低层模块&…...

Linux--进程替换

1.什么是进程替换 在fork函数之后&#xff0c;父子进程各自执行代码的一部分&#xff0c;但是如果子进程想要执行一份全新的程序呢&#xff1f; 通过进程替换来完成&#xff0c;进程替换就是父子进程代码发生写时拷贝&#xff0c;子进程执行自己的功能。 程序替换就是通过特定的…...

【计算机网络】TCP协议

文章目录 1. TCP报文的结构2. TCP的发送缓冲区和接收缓冲区3. 确保可靠性序列号和确认序列号确认应答超时重传连接管理1️⃣三次握手建立连接2️⃣四次挥手断开连接 4. 提高性能流量控制滑动窗口拥塞控制延迟应答捎带应答 5. 面向字节流6. TCP/UDP对比 概念&#xff1a;TCP&…...

机器学习数据集:Kaggle

什么是Kaggle&#xff1f; Kaggle成立于2010年&#xff0c;是一个进行数据发掘和预测竞赛的在线平台。从公司的角度来讲&#xff0c;可以提供一些数据&#xff0c;进而提出一个实际需要解决的问题&#xff1b;从参赛者的角度来讲&#xff0c;他们将组队参与项目&#xff0c;针…...

软考 系统架构设计师系列知识点之设计模式(4)

接前一篇文章&#xff1a;软考 系统架构设计师系列知识点之设计模式&#xff08;3&#xff09; 所属章节&#xff1a; 老版&#xff08;第一版&#xff09;教材 第7章. 设计模式 第2节. 设计模式实例 3. 行为型模式 行为型模式可以影响一个系统的状态和行为流。通过优化状态…...

PyCharm 安装 cx_Oracle 失败

我在PyCharm的终端用 pip安装cx_Oracle失败&#xff0c;报错情况如下&#xff1a; ERROR: Could not build wheels for cx_Oracle, which is required to install pyproject.toml-based projects 出错原因&#xff1a; python 的版本太高了&#xff0c;我的是3.11版本的&…...

解决Windows出现找不到mfcm90u.dll无法打开软件程序的方法

今天&#xff0c;我非常荣幸能够在这里与大家分享关于mfc90u.dll丢失的5种解决方法。在我们日常使用电脑的过程中&#xff0c;可能会遇到一些软件或系统错误&#xff0c;其中之一就是mfc90u.dll丢失。那么&#xff0c;mfc90u.dll究竟是什么文件呢&#xff1f;接下来&#xff0c…...

如何设计线程安全的 HashMap?

如何设计线程安全的 HashMap? HashMap 线程不安全的体现&#xff1a; 多线程下扩容死循环&#xff1a;JDK1.7中的 HashMap 使用头插法插入元素&#xff0c;在多线程的环境下&#xff0c;扩容的时候有可能导致环形链表的出现&#xff0c;形成死循环。因此&#xff0c;JDK1.8使…...

rpc汇总

1、什么是rpc rpc的应用&#xff0c;有哪些 Google 开源了 gRPC&#xff0c; Facebook 开源了 Thrift&#xff0c; Twitter 开源了 Finagle&#xff0c; 百度开源了bRPC&#xff0c; 腾讯开源了 Tars&#xff0c; 阿里开源了 Dubbo 和 HSF&#xff0c; 新浪开源了 Motan 等 gr…...

OpenCV学习(五)——图像基本操作(访问图像像素值、图像属性、感兴趣区域ROI和图像边框)

图像基本操作 5. 图像基本操作5.1 访问像素值并修改5.2 访问图像属性5.2 图像感兴趣区域ROI5.3 拆分和合并图像通道5.4 为图像设置边框&#xff08;填充&#xff09; 5. 图像基本操作 访问像素值并修改访问图像属性设置感兴趣区域&#xff08;ROI&#xff09;分割和合并图像 …...

指针仪表读数YOLOV8NANO

指针仪表读数YOLOV8 NANO 采用YOLOV8 NANO训练&#xff0c;标记&#xff0c;然后判断角度&#xff0c;得出角度&#xff0c;可以通过角度&#xff0c;换算成数据...

10000字!图解机器学习特征工程

文章目录 引言特征工程1.特征类型1.1 结构化 vs 非结构化数据1.2 定量 vs 定性数据 2.数据清洗2.1 数据对齐2.2 缺失值处理 原文链接&#xff1a;https://www.showmeai.tech/article-detail/208 作者&#xff1a;showmeAI 引言 上图为大家熟悉的机器学习建模流程图&#xff0c;…...

Java 官方提供了哪几种线程池,分别有什么特点?

JDK 中提供了 5 中不同线程池的创建方式&#xff1a; newCachedThreadPool newCachedThreadPool&#xff0c; 是一种可以缓存的线程池&#xff0c;它可以用来处理大量短期的突发流量。 它的特点有三个&#xff0c;最大线程数是 Integer.MaxValue&#xff0c;线程存活时间是 60 …...

DTI-ALPS处理笔记

DTI-ALPS处理笔记 前言: 前段时间刚好学习了一下DTI-ALPS处理(diffusion tensor image analysis along the perivascular space ),记录一下,以便后续学习。ALPS是2017年发表在《Japanese Journal of Radiology》的一篇文章首次提出的 (文章地址),主要用于无创评估脑内淋…...

LVS集群-NAT模式

集群的概念&#xff1a; 集群&#xff1a;nginx四层和七层动静分离 集群标准意义上的概念&#xff1a;为解决特定问题将多个计算机组合起来形成一个单系统 集群的目的就是为了解决系统的性能瓶颈。 垂直扩展&#xff1a;向上扩展&#xff0c;增加单个机器的性能&#xff0c;…...

微服务技术导学

文章目录 微服务结构认识微服务技术栈 微服务结构 技术&#xff1a; 解决异常定位&#xff1a; 持续集成&#xff0c;解决自动化的部署&#xff1a; 总结如下&#xff1a; 认识微服务 微服务演变&#xff1a; 技术栈 SpringCloud与SpringBoot版本对应关系...

p5.js 开发点彩画派的绘画工具

本文简介 点赞 关注 收藏 学会了 这几天在整理书柜时看到这套书&#xff0c;看到梵高&#xff0c;想起他的点彩画。 想到点彩画派&#xff0c;不得不提的一个画家叫乔治皮埃尔秀拉。据说梵高也模仿过他的画作。 我引用一下维基百科对点彩画派的解析&#xff1a; 点彩画派&…...

Java工具库——Commons IO的50个常用方法

工具库介绍 Commons IO&#xff08;Apache Commons IO&#xff09;是一个广泛用于 Java 开发的开源工具库&#xff0c;由Apache软件基金会维护和支持。这个库旨在简化文件和流操作&#xff0c;提供了各种实用工具类和方法&#xff0c;以便更轻松地进行输入输出操作。以下是 Com…...

Git: 仓库clone和用户配置

git clone 两种方式clone远程仓库到本地。 通过ssh 命令格式&#xff1a; git clone gitxxxxxx.git使用这种方法需要提前创建ssh秘钥。 首先打开一个git控制台&#xff0c;输入命令 ssh-keygen -t ed25519 -C “xxxxxxxxxx.com”输入命令后需要点击四次回车&#xff0c;其…...