内存泄漏-gpu/gpu\_rs(KERNEL\_MEMORY)问题排查
====================================

#### 问题现象

应用在使用过程中出现闪退，hilog日志中PROCESS\_KILL的Reason为ResourceLeak:Gpu Leak或RENDER\_MEMORY\_OVER\_ERROR，memory\_leak目录中生成memleak-kernel-\[process\_name\]-0-sample和memleak-kernel-\[process\_name\]-0-\[timestamp\]的内存泄漏日志文件。

#### 背景知识

*   gpu泄漏是指在应用运行过程中，未能及时释放gpu内存资源，导致内存持续占用且无法被回收。
*   gpu\_rs内存泄漏与gpu泄漏的区别在于：gpu是应用自渲染发生的泄漏，gpu\_rs是通过进程render\_service进行统一渲染发生的泄漏。
*   gpu泄漏的检测机制是通过内核监控整机节点信息，当gpu内存使用量超过软门限8个采样周期或直接超过硬门限，就会判定泄漏，触发对应用的管控。
*   应用如果通过render\_service进行统一渲染（直接向renderservice发送绘制指令），那么会在render\_service中申请gpu内存，如果单个应用通过RS申请的gpu内存超过2G，那么会触发RS进程对应用的管控RENDER\_MEMORY\_OVER\_ERROR，同步会通过泄漏检测模块上报资源泄漏事件GPU\_RS。
*   应用被管控后，会在“/data/log/memory\_leak/”目录生成两个故障日志文件以供分析：
    *   memleak-native-\[process\_name\]-\[pid\]-0-sample.txt：采样日志文件，用于观察内存增长趋势，确认泄漏情况。
    *   memleak-native-\[process\_name\]-\[pid\]-0-\[timestamp\].txt：维测日志文件，记录了一些内存相关的统计信息，用于不同泄漏问题的维测。
*   DevEco Profiler提供了基础的内存场景分析Allocation，可以使用Allocation来分析应用或元服务在运行时的内存分配及使用情况，识别和定位内存泄漏、内存抖动以及内存溢出等问题，对应用或元服务的内存使用进行优化，参考文档[内存分析介绍](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/ide-insight-session-allocations-memory)。

#### 问题定位

应用进程触发gpu泄漏的管控后，系统会抓取泄漏相关的信息，在memory\_leak目录生成两个故障日志文件以供分析。

1.  **分析采样日志memleak-native-\[process\_name\]-\[pid\]-sample.txt。**
    
    排查内存增长情况，是否超过了hardThreshold门限，或是超过softThreshold门限8个检测周期未下降。
    
    日志如下：
    
    memoryName:gpu
    softThreshold:2300(MB)
    hardThreshold:3450(MB)
    topMemory:2750912(KB)
    
    time(s) kernelMemory(KB)realtime
    _// ..._
    20              82987           1544200         2026/01/21 09:37:33
    21              83208           2546040         2026/01/21 09:41:13
    22              83428           2540460         2026/01/21 09:44:53
    23              83648           2750912         2026/01/21 09:48:45
    24              83868           2494756         2026/01/21 09:52:25
    25              84088           2650208         2026/01/21 09:56:05
    26              84308           2484484         2026/01/21 10:03:42
    27              84528           2497212         2026/01/21 10:07:22
    28              84748           2643384         2026/01/21 10:11:12
    
2.  **分析维测日志memleak-native-\[process\_name\]-\[pid\]-0-\[timestamp\]**
    
    日志规格主要为头部通用信息、整机内存概览信息、内存节点信息和RS进程的内存使用情况。
    
    Generated by HiviewDFX @OpenHarmony
    LOGGER\_MEMCHECK\_GERNAL\_INFO		<- 头部通用信息
    memoryName:\[gpu/gpu\_rs\]
    softThreshold:2300(MB)
    hardThreshold:3450(MB)
    appHardThreshold:4096(MB)
    topMemory:2750912(KB)
    
    \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
    LOGGER\_MEMCHECK\_MEMINFO		<- 整机内存概览信息
    MemTotal:                             11731076 kB
    AshmemUsed:                             198375 kB
    IonTotalUsed:                          1155076 kB
    GpuTotalUsed:                          2640712 kB
    ReclaimAvailBuffer:                    1722368 kB
    realtime:	2026/01/21 10:11:12
    
    \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
    LOGGER\_MEMCHECK\_PROC\_INFO		<- 内存节点信息
    ctx\_101      10648      10648 used summary:28672 grow:0 driver:28672 kmd:0 jit:0
    ctx\_65      20246      20056 used summary:2324946944 grow:11534336 driver:6557696 kmd:557056 jit:0
    进程名:
    Channel: Texture (Total memory: 2253957888)
    26:                   24 / 1187905536
    Total used memory: 2370686388
    Total allocated memory: 2396626944
    Total purged memory: 0
    Total using heap: 22
    \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
    LOGGER\_MEMCHECK\_RENDER\_SERVICE\_MEM		<- RS进程的内存使用情况
    get info realtime:	2026/01/21 10:11:12
    -------------------------------\[ability\]-------------------------------
    ----------------------------------RenderService----------------------------------
    dumpMem: 
    ----------
    RenderService caches:
    RSImageCache:
          Size	            Type	    Type,UseCnt,IsUnMap,UnMapCnt	     Pid	                 Wid	     Uid	                             SurfaceName
    
    1.  从LOGGER\_MEMCHECK\_PROC\_INFO内存节点信息中搜索关键字used summary，排查gpu内存使用量最高的进程。
    2.  排查进程gpu内存的分布情况，观察内存占用异常的gpu内存类型，以及各大小内存申请分布状况。
        
        示例：Render Service进程的vulkan image和vulkan buffer占用过高。
        
        vulkan主要用于纹理渲染等用途，从vulkan image中看到，224~225大小的图片资源，共有10次申请，占用约334MB，占Total memory比例很高；从vulkan buffer中看到，225~226大小的buffer资源，共有13次申请，占用约436MB，占Total memory比例很高；需根据场景以及纹理申请大小排查泄漏点。
        
        ctx\_4        923        880 used summary:4096 grow:0 driver:4096 kmd:0 jit:0
        ctx\_3       1893       1482 used summary:3239936 grow:0 driver:1134592 kmd:1064960 jit:0
        ctx\_1       1893       1482 used summary:1398829056 grow:0 driver:4509696 kmd:1064960 jit:1441792
        render\_service
        Total U(device): 875046670
        Total A(device): 1258405888
        Total P(device): 35000320
        Total U(host): 57258710
        Total A(host): 74153984
        Total P(host): 8192
        C: vulkan default device : 4837602
        C: vulkan image : 399937536
        C: vulkan buffer : 459800576
        C: vulkan fcp : 523720
        C: vulkan program : 4080900
        C: vulkan crc buffer : 2898432
        C: vulkan hebc header : 2967904
        C: cq memory(not in total memory) : 3325952
        C: host memory : 57258710
        C: vulkan external memory(not in total memory) : 202035200
        C: vulkan image (Total memory: 399937536)
          13:                    9 / 36864
          16:                   16 / 524288
          17:                   20 / 1310720
          18:                    6 / 884736
          19:                   46 / 17039360
          20:                    4 / 2588672
          21:                    3 / 3670016
          22:                    3 / 11468800
          24:                    2 / 28180480   
          25:                   10 / 334233600   
        _// 25表示image大小，范围在2^24~2^25；10表示个数；334233600表示内存占用大小，单位Byte。_
         C: vulkan buffer (Total memory: 459800576)
          20:                    5 / 2621440
          21:                    4 / 4194304
          22:                    2 / 4194304
          23:                    3 / 12582912
          26:                   13 / 436207616
        _// 26表示buffer大小，范围在2^25~2^26；13表示个数；436207616表示内存占用大小，单位Byte。_
        
    
3.  **结合业务代码分析泄漏点。**
    
    根据使用场景，在开发态使用Allocation模板抓取内存栈信息，分析内存申请释放情况。参考[基础内存：Allocation分析](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/ide-insight-session-allocations)。
    
    排查方向：
    
    *   应用自渲染：
        *   VK内存申请/释放没有配对vkAllocateMemory/vkFreeMemory。
        *   OpenGLES内存申请/释放没有配对。
            *   image创建和销毁：eglCreateImageKHR/eglDestroyImageKHR。
            *   buffer创建/销毁：glGenBuffers/glDeleteBuffers。
        *   OpenCL内存申请/释放没有配对。
            *   image创建/销毁：clCreateImage/clReleaseMemObject。
            *   buffer创建和销毁：clCreateBuffer/clReleaseMemObject。
    *   RS统一渲染：
        *   单次渲染了一个分辨率较高的超大图导致gpu内存超标。
        *   短时间内发送了过多的绘制指令导致RS侧累计的进程内存使用量超过阈值触发管控。
        *   应用通过list view无限创建Render node，导致RS的gpu内存部分持续走高，总内存也持续走高。
    

#### 分析结论

应用存在gpu内存泄漏，导致应用进程被终止。

#### 修改建议

程序需要正确管理分配的资源，使用完毕后需立刻释放。相关分析方法参考[gpu泄漏](https://developer.huawei.com/consumer/cn/doc/best-practices/bpta-stability-leak-way#section10302163291714)和[gpu\_rs泄漏](https://developer.huawei.com/consumer/cn/doc/best-practices/bpta-stability-leak-way#section174311514174111)。