You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何编写脚本解析Android应用.hprof文件,分析自定义容器内存浪费占比?

可以编写脚本解析.hprof文件分析自定义容器的内存浪费占比

完全可以通过脚本自动化分析自定义容器的内存使用情况,核心是利用hprof文件中记录的对象字段信息,提取自定义容器实例的总容量和已使用元素数两个关键指标,进而计算未使用空间的占比。

核心分析逻辑

你的自定义容器和ArrayList逻辑类似,必然包含两个核心字段:

  • 内部存储元素的数组(比如elements或elementArray),其length就是容器的总容量
  • 记录当前已添加元素数量的字段(比如size)

未使用空间占比的计算公式为:
未使用占比 = (总容量 - 已使用元素数) / 总容量 * 100%

具体实现方案

1. 预处理Android hprof文件

Android生成的hprof格式和标准JVM hprof略有差异,需要先用Android SDK自带的hprof-conv工具转换格式:

hprof-conv your-app.hprof standard-format.hprof

2. 脚本化解析方式

方式一:用MAT的OQL查询+脚本统计

Memory Analyzer Tool(MAT)支持对象查询语言(OQL),可以直接筛选出自定义容器实例并计算占比,步骤如下:

  1. 用MAT打开转换后的hprof文件
  2. 打开OQL控制台,输入查询语句(替换为你的容器类名和字段名):
SELECT 
    this,
    this.elements.length AS totalCapacity,
    this.size AS usedSize,
    ((this.elements.length - this.size)/this.elements.length)*100 AS wastePercentage
FROM com.your.package.YourCustomContainer
  1. 将查询结果导出为CSV文件,再用Python/Shell脚本批量计算整体平均占比、最大浪费占比等统计值。
方式二:用Java库编写解析脚本

可以使用Square的haha库(专门用于解析Android hprof)编写Java工具,直接批量处理并输出结果:

import com.squareup.haha.perflib.Heap;
import com.squareup.haha.perflib.HeapParser;
import com.squareup.haha.perflib.Instance;
import com.squareup.haha.perflib.ClassObj;
import com.squareup.haha.perflib.ObjectArray;
import java.io.File;

public class ContainerMemoryAnalyzer {
    public static void main(String[] args) throws Exception {
        Heap heap = HeapParser.parse(new File("standard-format.hprof"));
        ClassObj containerClass = heap.findClass("com.your.package.YourCustomContainer");
        
        int totalInstances = 0;
        double totalWasteRatio = 0.0;
        double maxWasteRatio = 0.0;

        for (Instance instance : containerClass.getInstances()) {
            totalInstances++;
            // 获取内部数组的总容量
            ObjectArray elementArray = (ObjectArray) instance.getField("elements").getValue();
            int totalCapacity = elementArray.getLength();
            // 获取已使用元素数
            int usedSize = instance.getField("size").getInt();
            // 计算浪费占比
            double wasteRatio = (double)(totalCapacity - usedSize) / totalCapacity;
            totalWasteRatio += wasteRatio;
            if (wasteRatio > maxWasteRatio) {
                maxWasteRatio = wasteRatio;
            }
            // 输出单个实例的情况
            System.out.printf("实例ID: %x, 总容量: %d, 已使用: %d, 浪费占比: %.2f%%%n", 
                instance.getId(), totalCapacity, usedSize, wasteRatio * 100);
        }

        // 输出整体统计结果
        if (totalInstances > 0) {
            double avgWasteRatio = totalWasteRatio / totalInstances;
            System.out.printf("\n整体统计: 实例总数 %d, 平均浪费占比: %.2f%%, 最大浪费占比: %.2f%%%n",
                totalInstances, avgWasteRatio * 100, maxWasteRatio * 100);
        }
    }
}

3. 注意事项

  • 必须确保自定义容器的字段名和类名完全匹配,比如内部数组可能叫buf而非elements,需要根据实际代码调整。
  • 如果容器有子类实现,需要在查询或解析时包含所有相关子类。
  • 对于超大hprof文件,建议使用命令行工具而非GUI工具,避免内存溢出。

内容的提问来源于stack exchange,提问作者T code

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 23:22:15