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

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

背景


最近项目在编译,编译多次之后,有挺多人反馈会出现 OOM 的,在项目的根目录下面会出现 hs_err_pid*.log 的错误文件。内容大概如下


ba613cd0cd5dd862aa9119325a3fffda_986d75087c70e2451098d7db560f5ab7.png


这个对我们的开发效率还是有挺大影响的,如果能够解决,对我们的开发效率还是有一定提升的。因此,我们尝试进行解决。


探索原因


从报错的信息来看,‘jar transform Thread’ 有时候的线程数非常多, 很有可能是同时开启的线程数过大,导致内存不足,最终 OOM。


从线程名是 ‘jar transform Thread’ ,根据经验,我们第一时间想到可能是 transform 相关的。


于是,我们找项目当中 transfrom 相关的, 从 buildScan 文件中,找 transfrom 相关的


fb2d08fd2cba75921afca90431a352e3_eb849ef08a0e458fad40bcf2b72ae5e7.png


发现主要有几个


  1. transformClassesWithRealmTransformerForDebug
  2. transformClassesWithCom.xx.xx.gradle.plugin.hilt.HiltContextWrapperRemovePluginForDebug
  3. transformDebugClassesWithAsm


很快我们找到 Hilt, Realm 里面 transform 里面的代码,发现里面的 Thread Name 都不是 jar transform Thread。那应该不是这两个的原因。


讨论之后,我们尝试 dump 编译时 Java 进程的内存信息,看能不能复现?


首先,我们先确定当前进程的 PID


3f54813fc697d6ccd7441b7088d02b80_866ad1c1111cb18d4cea18c4ca5fcbd2.png


接着我们借助 VisualVM 这个工具,dump 下 JVM 编译时候的进程,编译的时候发现,线程数有时候会越来越多。


8d5b928b41bcee5a74363bd3db617588_d9a5944a2d908522030cadd89d3126f3.png


于是,我们在想能不能 debug 创建线程的地方,于是,我们在 java.lang.Thread#setName 这里设置条件断点 name.contains("jar transform")


68430a733572f185653a402deeb9994a_59ccdb48be5daa03c640c2a9c2ddf636.png


debug gradle assembleDebug 任务,很快我们发现,调用栈关系如下


3c3091509e9f7dc3865e1d93114a8779_801af5630465093e10c0136ac0e0f7a9.png


我们重点关注到了几个跟线程相关的东西


198569d65064abc0735a474e26f3434a_dd634c46d7f1b94a1e364af2315c0573.png


我们跟踪进去,发现这个线程池的核心线程数设置为 2147483647


7c57a1829769f9a4fb689da6d33ca847_9ba168670059b22d7fd17b80844d4d33.png


而上面的线程数不断增多,并且线程名包括 “jar transform”, 那很有可能就是这个线程池了。


我们逐一排查,发现线程池 executor 是在这里传递进来的


49d4b957923d21bfc4234162925c704a_eab8bd761453da20b73167e6da720bd3.png


跟踪代码,很快我们发现创建改线程池 executor 的地方DefaultCachedClasspathTransformer#executor


bc9a1cdf42835b481d87105aab92365a_9ab0f1a3db06ac0bc742412bfe6d7e8e.png


他这里果然没有限制线程的数量。


而我们项目中的 gradle 代码是 6.9.1,于是在想,我们去跟官方最新代码对比一下。


相关文章
|
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
|
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应用的内存管理机制,分析常见的内存泄漏问题,并提出一系列实用的内存优化技巧。通过这些策略的实施,开发者可以显著减少应用的内存占用,避免不必要的后台服务,以及提高垃圾回收效率,从而延长设备的电池寿命并确保应用的流畅运行。
|
14天前
|
移动开发 测试技术 Android开发
构建高效的Android应用:从内存优化到用户体验
【4月更文挑战第16天】 在移动开发领域,打造一个高效的Android应用并非易事。它要求开发者深入理解系统资源管理,并兼顾流畅的用户体验设计。本文将探讨如何通过内存优化策略和界面响应性提升,来实现这一目标。我们将剖析内存泄漏的根本原因,提供定位与解决的实践方法,并讨论如何通过异步处理和UI线程优化来保持应用的流畅性。
12 0