当前位置: 首页 > 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…...

日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻

在如今就业市场竞争日益激烈的背景下&#xff0c;越来越多的求职者将目光投向了日本及中日双语岗位。但是&#xff0c;一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧&#xff1f;面对生疏的日语交流环境&#xff0c;即便提前恶补了…...

MODBUS TCP转CANopen 技术赋能高效协同作业

在现代工业自动化领域&#xff0c;MODBUS TCP和CANopen两种通讯协议因其稳定性和高效性被广泛应用于各种设备和系统中。而随着科技的不断进步&#xff0c;这两种通讯协议也正在被逐步融合&#xff0c;形成了一种新型的通讯方式——开疆智能MODBUS TCP转CANopen网关KJ-TCPC-CANP…...

代理篇12|深入理解 Vite中的Proxy接口代理配置

在前端开发中,常常会遇到 跨域请求接口 的情况。为了解决这个问题,Vite 和 Webpack 都提供了 proxy 代理功能,用于将本地开发请求转发到后端服务器。 什么是代理(proxy)? 代理是在开发过程中,前端项目通过开发服务器,将指定的请求“转发”到真实的后端服务器,从而绕…...

C#学习第29天:表达式树(Expression Trees)

目录 什么是表达式树&#xff1f; 核心概念 1.表达式树的构建 2. 表达式树与Lambda表达式 3.解析和访问表达式树 4.动态条件查询 表达式树的优势 1.动态构建查询 2.LINQ 提供程序支持&#xff1a; 3.性能优化 4.元数据处理 5.代码转换和重写 适用场景 代码复杂性…...

(一)单例模式

一、前言 单例模式属于六大创建型模式,即在软件设计过程中,主要关注创建对象的结果,并不关心创建对象的过程及细节。创建型设计模式将类对象的实例化过程进行抽象化接口设计,从而隐藏了类对象的实例是如何被创建的,封装了软件系统使用的具体对象类型。 六大创建型模式包括…...

关于uniapp展示PDF的解决方案

在 UniApp 的 H5 环境中使用 pdf-vue3 组件可以实现完整的 PDF 预览功能。以下是详细实现步骤和注意事项&#xff1a; 一、安装依赖 安装 pdf-vue3 和 PDF.js 核心库&#xff1a; npm install pdf-vue3 pdfjs-dist二、基本使用示例 <template><view class"con…...

ubuntu系统文件误删(/lib/x86_64-linux-gnu/libc.so.6)修复方案 [成功解决]

报错信息&#xff1a;libc.so.6: cannot open shared object file: No such file or directory&#xff1a; #ls, ln, sudo...命令都不能用 error while loading shared libraries: libc.so.6: cannot open shared object file: No such file or directory重启后报错信息&…...

LLaMA-Factory 微调 Qwen2-VL 进行人脸情感识别(二)

在上一篇文章中,我们详细介绍了如何使用LLaMA-Factory框架对Qwen2-VL大模型进行微调,以实现人脸情感识别的功能。本篇文章将聚焦于微调完成后,如何调用这个模型进行人脸情感识别的具体代码实现,包括详细的步骤和注释。 模型调用步骤 环境准备:确保安装了必要的Python库。…...

使用SSE解决获取状态不一致问题

使用SSE解决获取状态不一致问题 1. 问题描述2. SSE介绍2.1 SSE 的工作原理2.2 SSE 的事件格式规范2.3 SSE与其他技术对比2.4 SSE 的优缺点 3. 实战代码 1. 问题描述 目前做的一个功能是上传多个文件&#xff0c;这个上传文件是整体功能的一部分&#xff0c;文件在上传的过程中…...

DAY 45 超大力王爱学Python

来自超大力王的友情提示&#xff1a;在用tensordoard的时候一定一定要用绝对位置&#xff0c;例如&#xff1a;tensorboard --logdir"D:\代码\archive (1)\runs\cifar10_mlp_experiment_2" 不然读取不了数据 知识点回顾&#xff1a; tensorboard的发展历史和原理tens…...