Android 编译 gradle 内存 OOM 解决之路(二)

简介: Android 编译 gradle 内存 OOM 解决之路

对比官方 gradle 代码


我们首先 clone 官方代码 gradle,找到 DefaultCachedClasspathTransformer,

发现最新代码已经进行了修改,限制了线程的数量。改为跟 CPU 核心数挂钩。


3f54adebc21a5bae83ce5e9990e431f2_28697a03d66c1e3b3c664b4597557fdf.png


而他是在什么时候进行了修改了,其实很简单,我们可以借助 git 命令,找到他属于哪一个 TAG.


git tag --contains 2a1e74166bc82607e15de78002ef56582b34af0d


ef964aae64de99621944e20df271d82d_c32cf538489b08f26412029c7e8dc80b.png


很快我们发现了,他在 gradle 7.0 上面对线程池的线程数进行了限制,改为跟 CPU 核心数挂钩。


思考


先来思考一个问题,可能很多人有同样的疑问。


为什么有的机器没出现有的机器会出现,⽐如我同事的mac就没有发现

我么先来看一下 java tranfrom 线程是干什么用的,


我们可以看这里的代码

org.gradle.internal.classpath.DefaultCachedClasspathTransformer.TransformFile#schedule


8c0ea1e3df6cb15c992acc655c553ed0_2317890d1581e523e58f63c18bfe88ff.png


跟踪下去,你会发现主要是一些 IO 读取操作。


如果说你的机器磁盘性能比较好,那么 IO 读取比较快,线程干完工作之后,就会自动销毁,出现这样现象的可能性会比较低。如果磁盘性能较差,出现的可能性会比较大。


问题解决


既然怀疑问题是因为这里的线程数引起的,于是第一时间我们想到了几种方法


  1. 反射修改线程池的数量
  2. 升级 gradle 版本


于是,我们跟中代码,试试反射能不能修改代码,但很快,我们发现,并没有找到一个好的 hook 点,无法修改。


可能有人会想到 epic,没错,刚开始我也想用 epic。但是 epic 是基于安卓 ART 虚拟机的,而我们编译的时候,是基于 JVM 的,epic 是无法使用的。


接着我们尝试了第二种方法,尝试升级 gradle 版本到 7.0,折腾了一fang之后,发现升级要适配的东西还是蛮多的,一下子无法解决


  1. maven repo 仓库设置 allowInsecureProtocol
  2. grrovy 版本冲突
  3. JavaParser 错误


总之,错误是解决完一个接着一个,还是挺多坑的


柳暗花明又一村


跟汉光爷讨论之后,汉光爷说能不能自己编译一个版本出来。他在官网上找到了编译 gradle 版本的方法


2489a00d8ef6bf4bcd8b43164dd2b4a7_edf0bcfe06250af185979acb9f64bb65.png


编译完成之后,上传到 CC 的 S3 服务器上面,我们在 gradle-wrapper.properties 下面修改,替换成自己的 gradle 版本


#Thu May 30 18:31:45 CST 2019
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
# 解决编译线程数过多,导致 OOM 的问题
distributionUrl=https://xx.cn/static/gradle/gradle-6.9.3-all.zip


再次编译,可以看到 jar transform 相关的线程数,最多变为 8 了,因为我的电脑是 8 核单核心的。


4861434a8fcd328279615209d6d381fe_9e5c21f1127efd5d2894e55de85261d0.png


到此,我们对 gradle jar transfrom thread 的线程数进行了限制,合理应该是不会再出现 OOM 了,如果还会出现,可以保留现场,找我或者汉光看看。


总结


可以看到,我们这次的问题解决思路大概是这样的。


  1. 从 error 日志排查发现,很有可能跟 transfrom 相关
  2. 排查项目里面 transfrom 相关的,有没有 jar transform Thread 相关的
  3. dump JVM 内存,看线程相关的,观察 jar transform Thread 是否异常
  4. debug gradle assemble 任务,观察 线程名包括 jar transform Thread Thread 的调用堆栈
  5. 分析 调用堆栈,找到原因
  6. 结合 gradle 官方代码,查看问题是否已经解决


那有没有更快的方法呢?


其实如果一开始能确定是 gradle 问题的话,可以直接在 gradle 里面搜索字符串 jar transforms,然后再一步步反推,其实也是可以的。


相关文章
|
2月前
|
编解码 算法 Java
构建高效的Android应用:内存优化策略详解
随着智能手机在日常生活和工作中的普及,用户对移动应用的性能要求越来越高。特别是对于Android开发者来说,理解并实践内存优化是提升应用程序性能的关键步骤。本文将深入探讨针对Android平台的内存管理机制,并提供一系列实用的内存优化技巧,以帮助开发者减少内存消耗,避免常见的内存泄漏问题,并确保应用的流畅运行。
|
1天前
|
存储 缓存 数据库
构建高效Android应用:内存优化策略深度剖析
【4月更文挑战第29天】 在移动开发领域,性能一直是衡量应用质量的关键指标之一。特别是对于Android平台,由于设备硬件配置的多样性,内存管理成为开发者面临的一大挑战。本文将深入探讨Android应用内存优化的有效策略,旨在帮助开发者提升应用性能,减少内存消耗,避免常见的内存泄漏问题。通过对Android内存管理机制的分析与实际案例的结合,我们将提供一系列实用的优化技巧,助力应用在竞争激烈的市场中脱颖而出。
|
3天前
|
缓存 Java Android开发
构建高效的Android应用:从内存优化到电池寿命
【4月更文挑战第27天】在移动应用开发领域,尤其是对于资源有限的Android设备而言,性能优化是一个持续的挑战。本文将深入探讨如何提升Android应用的性能,重点讨论内存使用和电池寿命两大关键因素。我们将分析常见的内存泄漏问题,提供解决方案,并探究如何通过减少不必要的后台服务和优化网络请求来延长电池续航。文章的目标是为开发者提供实用的技术和策略,以构建更加高效、响应迅速且用户体验良好的Android应用。
|
3天前
|
存储 移动开发 Java
构建高效Android应用:从内存优化到电池使用
【4月更文挑战第27天】 在移动开发领域,一个流畅且高效的Android应用对于用户体验至关重要。本文将深入探讨如何提升应用性能,特别关注内存管理和电池寿命这两个关键方面。我们将透过具体策略和最佳实践,揭示如何减少不必要的资源消耗,延长设备电池续航,并保证应用响应迅速。通过分析内存分配原理、泄露预防技巧及电池使用效率的优化方法,开发者可以为自己的应用建立起一套性能优化机制。
|
5天前
|
缓存 移动开发 Android开发
构建高效Android应用:内存优化实战指南
【4月更文挑战第25天】 在移动开发领域,应用程序的性能至关重要。特别是对于Android设备,由于硬件配置的多样性,合理的内存管理与优化是提升应用流畅度、减少卡顿和崩溃的关键。本文将深入探讨Android应用的内存优化技巧,通过分析内存泄漏的原因、诊断工具的运用以及实际代码层面的改进措施,帮助开发者构建更加高效的Android应用。
|
7天前
|
存储 Java Shell
Android系统 实现低内存白名单防LMK原理分析
Android系统 实现低内存白名单防LMK原理分析
18 0
|
8天前
|
XML Java API
Android 浅度解析:系统框架层修改,编译,推送相关操作
Android 浅度解析:系统框架层修改,编译,推送相关操作
24 0
|
12天前
|
缓存 Java Android开发
构建高效Android应用:从内存优化到用户体验
【4月更文挑战第18天】 在移动开发领域,特别是针对Android系统,性能优化和内存管理是确保应用流畅运行的关键。本文将深入探讨如何通过各种技术手段提升Android应用的性能,包括内存使用优化、UI渲染效率提高以及响应速度加快等方面。文章不仅涉及理论分析,还包含了实用的代码示例和最佳实践建议,旨在帮助开发者构建出既节省资源又具有良好用户体验的高效Android应用。
|
12天前
|
移动开发 Android开发 开发者
构建高效Android应用:采用Kotlin进行内存优化的策略
【4月更文挑战第18天】 在移动开发领域,性能优化一直是开发者关注的焦点。特别是对于Android应用而言,由于设备和版本的多样性,确保应用流畅运行且占用资源少是一大挑战。本文将探讨使用Kotlin语言开发Android应用时,如何通过内存优化来提升应用性能。我们将从减少不必要的对象创建、合理使用数据结构、避免内存泄漏等方面入手,提供实用的代码示例和最佳实践,帮助开发者构建更加高效的Android应用。
|
14天前
|
缓存 移动开发 Java
构建高效的Android应用:内存优化策略
【4月更文挑战第16天】 在移动开发领域,尤其是针对资源有限的Android设备,内存优化是提升应用性能和用户体验的关键因素。本文将深入探讨Android应用的内存管理机制,分析常见的内存泄漏问题,并提出一系列实用的内存优化技巧。通过这些策略的实施,开发者可以显著减少应用的内存占用,避免不必要的后台服务,以及提高垃圾回收效率,从而延长设备的电池寿命并确保应用的流畅运行。