原创 抖音 Android 性能优化系列: Java 内存优化篇

发布时间:2021-08-02 23:43:39 浏览 3147 来源:猿笔记 作者:字节跳动技术团队

    需要运行过程中做到合理的资源分配与回收,尝试给大家分享一下抖音团队关于Java内存优化中的一些思考,在未对抖音内存进行专项治理之前我们梳理了一下整体内存指标的绝对值和相对崩溃。抖音这边通过前期归因、工具建设以及投入一个双月的内存专项治理将整体JavaOOM优化了百分之80。在对抖音的Java内存优化治理之前我们先根据平台上报的堆栈异常对当前的OOM进行归因,其中`pthread_create`和fd数量不足均为native内存限制导致的Java层崩溃,我们对这部分的内存问题也做了针对性优化:


    #主题列表:juejin,github,smartblue,cyanosis,channing-cyan,fancy,hydrogen,condensed-night-purple,greenwillow,v-green,vue-pro,healer-readable,mk-cute,jzman,geek-black

    #投稿主题:

    theme:juejin

    highlight:

    内存作为计算机程序运行中最重要的资源之一,需要在运行过程中进行合理的分配和回收。不合理的内存占用会导致用户应用运行停滞、ANR和黑屏,甚至导致OOM(内存不足)崩溃。颤音作为用户广泛使用的产品,需要在各种机器资源中保持出色的流畅性和稳定性,记忆优化是重要环节。



    本文结合JavaOOM内存优化的治理实践,尝试与大家分享颤音团队对Java内存优化的一些思考,包括工具构建和优化方法论。

    #抖音JavaOOM背景

    在颤音记忆特殊处理之前,我们梳理了整体记忆指数的绝对值和相对崩溃,发现比例很高。另外,记忆相关指标在去年春节期间再次飙升至历史新高,所以整体记忆问题相当严重,必须进行特殊处理。颤音方面,整个JavaOOM通过前期归属、工具构建、两个月专用内存管理,优化了80%。

    ##JavaOOMTop堆栈归因

    在优化颤音的Java内存管理之前,我们先根据平台上报的堆栈异常属性当前的OOM,主要分为以下几类:

    图1.OOM分类

    其中‘pthread _ create’的问题约占总数的50%,Java堆内存溢出40%以上,其余为少量fd溢出。其中‘pthread _ create’和fd不足是本机内存限制导致的Java层崩溃,我们也针对这部分内存问题做了针对性的优化,主要包括:

    -线程聚合,监控

    -自动修复螺纹堆栈泄漏

    -FD泄漏监控

    -虚拟内存监控和优化

    -颤音64位特殊

    治理后的pthread _ create’问题降低到0.02‰以下,这方面的治理实践将在下一次颤音Native内存治理实践中详细介绍,敬请期待。本文主要研究Java堆内存管理。

    #堆内存治理理念

    从Java堆内存溢出的分类来看,主要有两种类型的问题:

    **1.堆内存太大,无法进行单次分配* *。

    触发这类问题的原因是由于数据异常导致的单内存分配过大超限,部分是由于StringBuilder拼接的累积大小等造成的。这种问题的解决方法很简单,问题出在当前栈。

    **2.堆内存的累积分配达到最高* *。

    这类问题的问题栈会比较分散,在任何内存分配场景下都可能触发,那些高频内存分配节点的概率会比较高,比如位图内存分配。这种OOM的根本原因是内存占用过多,目前的栈只是压垮骆驼的最后一根稻草,并不是问题的根源。所以需要对整体内存分配进行分析,找出内存使用不合理的地方(比如内存泄漏、大对象、小对象太多、大图像等)。).

    #工具制造

    # #工具创意

    锋利的工具很管用。从以上内存治理思路来看,该工具需要解决的主要问题是分析整体内存分配,发现不合理的内存使用情况(比如内存泄漏、大对象、小对象过多等。).

    我们从离线和在线维度构建工具:

    ###线下

    线下工具是最先考虑的,在研发和测试的时候能够提前发现内存泄漏问题。业界的主流工具也是这个思路,比如AndroidStudioMemoryProfiler、LeakCanary、MemoryAnalyzer(MAT)。

    基于LeakCanary核心库,我们设计了一套在线自动分析和报告内存泄漏的工具。主要流程如下:

    图2。离线自动分析过程

    运行离线内存泄漏工具后,颤音发现了离线工具的各种缺点:

    1.检测到的内存泄漏太多,没有更好的优先级,因此R&D消耗不够,历史问题堆积如山。此外,很难与业务R&D沟通解决问题的好处,也很难调整解决离线内存泄漏问题的ROI(投入产出比)。

    2.离线场景可以运行到有限的场景,因此很难穷尽所有的用户场景。颤音用户基数大,经常会遇到一些在线OOM浪涌的问题,由于缺乏在线数据,找不到。

    3.3日收购HPORF。安卓端依赖原生debug . dumphporf’。转储过程会挂起主线程,导致明显的阻塞。离线使用体验差,R&D反馈经常影响测试。

    4.LeakCanary基于Shark分析引擎,分析速度较慢,通常需要5分钟以上才能完成,分析过程会影响进程内存占用。

    5.分析结果比较简单,只能分析Fragment和Activity的内存泄漏,不能分析大对象、小对象太多等问题导致的内存OOM。

作者信息

发布了 82 篇专栏 · 获得点赞 3810 · 获得阅读 332901

相关推荐 更多