moon-hprof

    Experimental HPROF heap dump parser for MoonBit.

    hprof
    jvm
    heap-dump
    Download zip
    Author
    Version
    0.2.0
    License
    Apache-2.0
    Last updated
    16 days ago
    Downloads
    33

    #moon-hprof

    MoonBit 编写的 HotSpot HPROF 堆转储解析库与命令行工具。支持类和对象索引、字段与数组查询、按类统计、JSON/CSV 导出、栈信息解析,以及两份转储的类统计比较。

    这是一个可通过源码或 MoonCake 使用的堆分析基础库,不是 Eclipse MAT 的完整替代品;提供基于 HPROF 显式引用的支配分析和 payload retained 统计,不提供自动泄漏判定或 JVM 实际 retained heap。MoonCake 已发布版本为 clhhhhhh/moon-hprof@0.2.0,最新 GC 分析功能可从仓库源码运行。

    项目采用 Apache-2.0。开发阶段使用 AI 辅助编程。

    验证数据由本仓库的 validation/GenerateHeap.java 生成,不使用用户业务进程的内存数据。第三方解析器仅作外部验证工具,不随包分发。

    #本地使用

    安装 MoonBit 工具链后:

    moon update moon check --target wasm --deny-warn moon build --target wasm --deny-warn moon test --target wasm --deny-warn moon run cmd/main --target wasm -- --help moon run cmd/main --target wasm -- summary path/to/heap.hprof moon run cmd/main --target wasm -- histogram path/to/heap.hprof --format csv --limit 20 moon run cmd/main --target wasm -- objects path/to/heap.hprof 0 --limit 10 moon run cmd/main --target wasm -- check path/to/heap.hprof

    首次使用前请在仓库根目录执行 moon update。运行 CLI 使用 moonrun 提供的文件能力,不是浏览器文件读取接口。CLI 输出到标准输出,可使用终端重定向保存 JSON 或 CSV。

    #功能与接口

    能力API / 命令
    索引与汇总parse、parse_with_limits、summary
    类、继承和静态字段class_info、hierarchy、static_fields、class
    对象查找与字段解码object_ids、instance_fields、field、objects、object
    数组分页array_values,支持八种基本类型及对象引用数组
    Java Stringjava_string,支持 char[]、Latin-1、compact UTF-16,字节顺序由调用者明确指定
    根引用与栈roots、roots_for、stack_trace、roots / stack 命令
    根可达性与支配分析gc_analysis API;CLI gc 输出可达对象、立即支配者和 retained payload
    GC Root 路径GCAnalysis::root_path;CLI root-path <object-id> 输出最短强引用路径
    直接引用references / refs,返回字段或数组引用,不进行可达性或泄漏推断
    反向引用与路径ReferenceIndex、incoming、referrer_ids、most_referenced、有预算的 path;CLI inbound / referenced
    内容预览与批量导出preview、objects_jsonl、previews_jsonl;CLI preview / export
    统计与比较histogram、select_histogram、totals、largest_objects、loader_statistics、compare_heaps
    导出JSON、RFC 4180 CSV;diff 比较两份转储
    校验validate / check,检查继承链、字段布局和元数据引用

    用 histogram 获得 class ID 后,可通过 objects <file> <class-id> 列出对象 ID,再以 object <file> <object-id> 查询。ID 支持无符号十进制和 0x 十六进制。objects 的 class ID 为 0 时列出全部普通对象和数组,不包含类对象;类对象使用 class 查询。

    例如:

    moon run cmd/main --target wasm -- summary heap.hprof --class java/lang/String moon run cmd/main --target wasm -- histogram heap.hprof --prefix java/ --sort payload --format json moon run cmd/main --target wasm -- object heap.hprof 0x1234 --offset 0 --limit 20 moon run cmd/main --target wasm -- diff before.hprof after.hprof moon run cmd/main --target wasm -- inbound heap.hprof 0x1234 --limit 20 moon run cmd/main --target wasm -- preview heap.hprof 0x1234 --limit 8 moon run cmd/main --target wasm -- export heap.hprof 0 --limit 100 > objects.jsonl moon run cmd/main --target wasm -- gc heap.hprof --limit 20 moon run cmd/main --target wasm -- root-path heap.hprof 0x1234

    其中 0x1234 是占位 ID,请替换成文件中的实际 ID。--offset、--limit 支持数组页面、根列表和对象列表,具体参数见 --help。

    #数据含义与支持边界

    • 支持 JAVA PROFILE 1.0.2、4/8 字节标识符、分段和非分段堆记录,以及标准 HotSpot GC 根类型。不支持 Android 专有扩展;未知堆子记录报错,未知顶层记录按长度跳过。
    • 文本支持 Java Modified UTF-8 和标准四字节 UTF-8。无法表示为有效 Unicode 标量的孤立代理项明确报错,不默默替换。
    • payload_bytes 是文件中实例字段或数组元素的字节数,不是 shallow heap、retained heap 或 JVM 总内存占用。类定义的 reported_instance_size 保留文件字段原值。
    • JSON 中对象 ID、时间戳及 64 位整数使用十进制字符串;NaN/Infinity 以带类型的字符串表达,避免 JSON 精度损失和非法数值。
    • 直方图按 class ID 区分类加载器。count_class 及跨转储比较按类名聚合;比较结果不证明同一对象跨 GC 存活。
    • java_string 对 compact UTF-16 必须明确原 JVM 的本机字节顺序。HPROF 没有直接携带这一信息。它解码字符串内容,不推断业务语义。
    • 输入完整加载到内存,再保存对象偏移和元数据索引;没有 mmap 或流式文件读取。默认文件上限 512 MiB、普通对象/数组上限 200 万、类上限 20 万,可通过 ParseLimits 调整;CLI 使用默认值。文件上限在读取后检查,不能替代调用者读取前的大小检查。
    • 查询页最多 100000 项;导出单个对象不会展开整个引用图。当前验证目标是 Windows/JDK 24 与 Ubuntu/JDK 21 的小型真实样本,不承诺大型转储性能或任意 JVM 兼容性。
    • ReferenceIndex 索引实例字段、静态字段、对象数组和 HPROF 类转储中的类加载器/父类/常量池引用,并补上对象到其类对象的隐式关系。普通路径查询不从 GC Roots 起步,也不判断可达性或泄漏。
    • gc_analysis 从 HPROF GC Roots 遍历强引用图,忽略 java/lang/ref/Reference.referent,用迭代立即支配者算法生成支配树,再按树后序累加 retained_payload;root_path 提供最短强引用路径。该指标是文件 payload 字节,不等同于 JVM 实际 shallow heap 或完整 MAT retained heap;SoftReference 的内存压力语义和 VM 私有边也无法仅凭通用 HPROF 记录完全还原。
    • 反向索引默认最多 100 万非空边、1000 万引用槽(包括空槽),超限明确报错。引用目标排行区分边数与不同源对象数,并标识指向堆中未定义对象的引用。
    • 对象预览只展示一层,省略项和字符裁剪会标记 truncated。JSON Lines 导出按对象分页,每行一个 JSON 文档;数组元素另有上限,不递归展开引用。

    #真实 JVM 对照验证

    需要 JDK(含 java 和 javac)及 PowerShell;CI 使用 Ubuntu、JDK 21,本地首次使用 Windows、JDK 24。执行:

    ./validation/verify.ps1 -Jdk '你的JDK安装目录'

    脚本固定使用外部 eaftan/hprof-parser 的提交 849678cca7c69eb8a25a927ad7836ad94bb02aef(Apache-2.0),并校验其 Guava 16.0.1 依赖的 SHA-256。两者仅用于外部验证,保存在忽略目录 _tools/。本仓库的 ReferenceCounts.java 只接收参考解析器回调,不实现二进制解码。

    脚本在默认配置和关闭压缩指针两种模式下分别生成真实转储,核对类、实例、对象数组、基本类型数组的总数,并断言自建 Marker 类恰有 37 个实例。随后运行 cmd/verify,检查继承 long 字段、静态对象引用、Marker 顺序、八种基本类型数组、NaN/Infinity,以及包含 NUL、中文和表情的 String。任何编译、解析或对照不一致都会导致验证失败。

    本地 Windows/JDK 24 已通过上述双配置对照和字段语义验证。JVM 版本和环境会改变系统类与对象数量;脚本比较同一次生成的文件,不把系统对象数量作为跨环境固定答案。真实样本的 ID 宽度由 JVM 决定;4/8 字节完整索引、字段和数组解码另有合成测试,这不等于已验证所有 32 位 JVM 转储。

    #当前验证边界

    90 个单元测试覆盖二进制边界、完整合成文件的所有截断前缀、重复/空 ID、数值位模式、类型解码、继承循环、字段遮蔽、数组、元数据、资源上限、类加载器统计、Unicode、JSON/CSV/JSON Lines、正反向引用、循环路径与预算截断、对象预览、多根/分叉支配、弱引用排除、retained 累加、GC Root 路径、CLI 和描述符。真实文件对照另在 CI 执行,不计入这个单元测试数量。

    2026-10-18 的 Git 跟踪 .mbt 文件合计 4735 行:实现和可执行程序 3025 行,测试 1710 行。该统计包含注释及空行,不包含生成的 .mbti 接口文件、Java 验证代码或第三方源码;行数不代表生产成熟度。

    GitHub Actions 执行 WASM 目标的 check/build/test,然后在 Linux/JDK 21 上重新生成样本并运行独立对照与语义验证。工具链版本、输入来源、参考解析器版本和边界均可在仓库内追溯。

    #项目结构

    • parser.mbt / model.mbt:边界读取、记录解析和数据模型。
    • query.mbt / validate.mbt:索引查询、类型与结构校验。
    • export.mbt / report.mbt:导出、过滤排序、统计与比较。
    • references.mbt / reference_report.mbt / preview.mbt:反向索引、有预算的路径查询、引用排行、对象预览和 JSON Lines。
    • text.mbt / strings.mbt / descriptor.mbt:Unicode、Java String 和 JVM 描述符。
    • limits.mbt / cli.mbt:资源限制和命令渲染。
    • cmd/main:CLI;cmd/verify:真实样本语义断言;validation:生成和独立对照。

    #来源与许可证

    按 HPROF 记录结构编写 MoonBit 实现,参考 eaftan/hprof-parser(Apache-2.0)理解记录及验证行为。第三方仓库和 Guava 验证依赖不会提交或随包分发。测试转储由自己的 Java 样本程序生成,二进制堆文件被 Git 忽略。项目及样本程序采用根目录 LICENSE 的 Apache-2.0 许可证。

    ParseError

    pub suberror ParseError {
    Invalid(Int, String)
    } derive(
    Debug
    )

    ClassInfo

    pub struct ClassInfo {
    id : UInt64
    stack_serial : UInt64
    superclass_id : UInt64
    loader_id : UInt64
    signers_id : UInt64
    protection_domain_id : UInt64
    instance_size : Int
    constants : Array[ConstantEntry]
    statics : Array[StaticField]
    fields : Array[FieldSpec]
    }

    ConstantEntry

    pub struct ConstantEntry {
    index : Int
    value : Value
    }

    FieldSpec

    pub struct FieldSpec {
    name_id : UInt64
    kind : Int
    }

    FieldValue

    pub struct FieldValue {
    declaring_class_id : UInt64
    name : String
    value : Value
    }

    GCAnalysis

    pub struct GCAnalysis {
    reachable : Array[UInt64]
    unreachable_ids : Array[UInt64]
    roots : Array[UInt64]
    dominator : Map[UInt64, UInt64]
    retained_payload : Map[UInt64, Int64]
    // private fields
    }

    GC-root reachability and dominator analysis over HPROF reference metadata. Sizes are sums of HPROF payload bytes, not JVM shallow or retained heap.

    GCAnalysis::dominator_of

    fn GCAnalysis::dominator_of(self : GCAnalysis, id : UInt64) -> UInt64?

    GCAnalysis::is_reachable

    fn GCAnalysis::is_reachable(self : GCAnalysis, id : UInt64) -> Bool

    GCAnalysis::retained_payload

    fn GCAnalysis::retained_payload(self : GCAnalysis, id : UInt64) -> Int64

    GCAnalysis::root_path

    fn GCAnalysis::root_path(self : GCAnalysis, target : UInt64) -> GCRootPath raise ParseError

    Return the shortest strong-reference path from any recorded GC root.

    GCAnalysis::to_json

    fn GCAnalysis::to_json(self : GCAnalysis, limit? : Int) -> Json raise ParseError

    JSON report with root/reachability counts and the highest retained payloads.

    GCRootPath

    pub struct GCRootPath {
    root_id : UInt64
    edges : Array[ReferenceEdge]
    }

    GCRootPath::to_json

    fn GCRootPath::to_json(self : GCRootPath) -> Json

    HeapTotals

    pub struct HeapTotals {
    class_objects : Int
    instance_objects : Int
    array_objects : Int
    payload_bytes : Int64
    array_elements : Int64
    largest_payload_id : UInt64
    largest_payload_bytes : Int
    }

    HistogramDelta

    pub struct HistogramDelta {
    name : String
    kind : String
    before_count : Int
    after_count : Int
    count_delta : Int64
    payload_delta : Int64
    }

    HistogramDelta::to_json

    fn HistogramDelta::to_json(self : HistogramDelta) -> Json

    HistogramRow

    pub struct HistogramRow {
    name : String
    class_id : UInt64
    loader_id : UInt64
    kind : String
    count : Int
    payload_bytes : Int64
    elements : Int64
    }

    Histogram row for one class identity or primitive-array element type.

    HistogramRow::to_json

    fn HistogramRow::to_json(self : HistogramRow) -> Json

    HistogramSort

    pub enum HistogramSort {
    Count
    Payload
    Elements
    Name
    }

    LoaderStatistics

    pub struct LoaderStatistics {
    loader_id : UInt64
    class_count : Int
    instance_count : Int
    array_count : Int
    payload_bytes : Int64
    }

    Aggregates by class-loader object ID; zero is the bootstrap/primitive group.

    LoaderStatistics::to_json

    fn LoaderStatistics::to_json(self : LoaderStatistics) -> Json

    MethodSignature

    pub struct MethodSignature {
    parameters : Array[String]
    return_type : String
    parameter_slots : Int
    }

    MethodSignature::display

    fn MethodSignature::display(self : MethodSignature) -> String

    ObjectInfo

    pub struct ObjectInfo {
    id : UInt64
    kind : ObjectKind
    class_id : UInt64
    stack_serial : UInt64
    primitive_kind : Int
    length : Int
    payload_offset : Int
    payload_bytes : Int
    }

    Payload byte lengths describe the file, never JVM allocation/retained size.

    ObjectKind

    pub enum ObjectKind {
    Instance
    ObjectArray
    PrimitiveArray
    } derive(Eq)

    ObjectKind::equal

    fn ObjectKind::equal(ObjectKind, ObjectKind) -> Bool

    ObjectKind::label

    fn ObjectKind::label(self : ObjectKind) -> String

    ObjectKind::not_equal

    fn ObjectKind::not_equal(x : ObjectKind, y : ObjectKind) -> Bool

    ObjectPreview

    pub struct ObjectPreview {
    id : UInt64
    kind : String
    class_name : String
    payload_bytes : Int
    array_length : Int?
    text : String
    truncated : Bool
    }

    ObjectPreview::to_json

    fn ObjectPreview::to_json(self : ObjectPreview) -> Json

    ParseLimits

    pub struct ParseLimits {
    max_file_bytes : Int
    max_objects : Int
    max_classes : Int
    max_strings : Int
    max_text_bytes : Int
    max_roots : Int
    max_records : Int
    max_trace_frames : Int
    }

    Limits bound indexing allocations. The caller still owns the input buffer.

    ParseLimits::new

    fn ParseLimits::new(max_file_bytes? : Int, max_objects? : Int, max_classes? : Int, max_strings? : Int, max_text_bytes? : Int, max_roots? : Int, max_records? : Int, max_trace_frames? : Int) -> ParseLimits raise ParseError

    ParseLimits::validate

    fn ParseLimits::validate(self : ParseLimits) -> Unit raise ParseError

    ReferenceEdge

    pub struct ReferenceEdge {
    source_id : UInt64
    target_id : UInt64
    label : String
    }

    ReferenceEdge::to_json

    fn ReferenceEdge::to_json(self : ReferenceEdge) -> Json

    ReferenceIndex

    pub struct ReferenceIndex {
    // private fields
    }

    Reusable bidirectional index of recorded object references.

    ReferenceIndex::build

    fn ReferenceIndex::build(heap : Summary, max_edges? : Int, max_slots? : Int) -> ReferenceIndex raise ParseError

    Builds once for repeated inbound/outbound queries. Exhausted budgets fail explicitly instead of returning an incomplete index that appears complete.

    ReferenceIndex::edge_count

    fn ReferenceIndex::edge_count(self : ReferenceIndex) -> Int

    ReferenceIndex::incoming

    fn ReferenceIndex::incoming(self : ReferenceIndex, id : UInt64, offset? : Int, limit? : Int) -> Array[ReferenceEdge] raise ParseError

    ReferenceIndex::most_referenced

    fn ReferenceIndex::most_referenced(self : ReferenceIndex, limit? : Int) -> Array[ReferencedObject] raise ParseError

    Ranks targets by distinct referring objects, then edge count, then ID. Multiple array slots or fields in one source are not multiple sources.

    ReferenceIndex::outgoing

    fn ReferenceIndex::outgoing(self : ReferenceIndex, id : UInt64, offset? : Int, limit? : Int) -> Array[ReferenceEdge] raise ParseError

    ReferenceIndex::path

    fn ReferenceIndex::path(self : ReferenceIndex, source : UInt64, target : UInt64, max_depth? : Int, max_nodes? : Int, max_edges? : Int) -> ReferencePath raise ParseError

    Bounded breadth-first search, reporting truncation separately from no path. Search only follows the indexed edge kinds, not VM/class-loader metadata.

    ReferenceIndex::referrer_ids

    fn ReferenceIndex::referrer_ids(self : ReferenceIndex, id : UInt64, offset? : Int, limit? : Int) -> Array[UInt64] raise ParseError

    Distinct source objects, unlike incoming(), which preserves every edge.

    ReferenceIndex::slot_count

    fn ReferenceIndex::slot_count(self : ReferenceIndex) -> Int

    ReferencePath

    pub struct ReferencePath {
    found : Bool
    truncated : Bool
    visited_nodes : Int
    inspected_edges : Int
    edges : Array[ReferenceEdge]
    }

    ReferencePath::to_json

    fn ReferencePath::to_json(self : ReferencePath) -> Json

    ReferencedObject

    pub struct ReferencedObject {
    object_id : UInt64
    reference_count : Int
    source_count : Int
    present_in_heap : Bool
    }

    Direct reference counts only; source_count does not measure retained size.

    ReferencedObject::to_json

    fn ReferencedObject::to_json(self : ReferencedObject) -> Json

    ResolvedFrame

    pub struct ResolvedFrame {
    id : UInt64
    class_name : String
    method_name : String
    signature : String
    source_name : String
    line_number : Int
    }

    ResolvedFrame::readable_signature

    fn ResolvedFrame::readable_signature(self : ResolvedFrame) -> String raise ParseError

    ResolvedFrame::to_json

    fn ResolvedFrame::to_json(self : ResolvedFrame) -> Json

    RootInfo

    pub struct RootInfo {
    tag : Int
    object_id : UInt64
    related_id : UInt64
    thread_serial : UInt64
    frame_number : UInt64
    }

    RootInfo::label

    fn RootInfo::label(self : RootInfo) -> String

    RootInfo::to_json

    fn RootInfo::to_json(self : RootInfo) -> Json

    StackFrame

    pub struct StackFrame {
    id : UInt64
    method_name_id : UInt64
    signature_id : UInt64
    source_name_id : UInt64
    class_serial : UInt64
    line_number : Int
    }

    StackTrace

    pub struct StackTrace {
    serial : UInt64
    thread_serial : UInt64
    frame_ids : Array[UInt64]
    }

    StaticField

    pub struct StaticField {
    name_id : UInt64
    value : Value
    }

    Summary

    pub struct Summary {
    id_size : Int
    classes : Int
    instances : Int
    object_arrays : Int
    primitive_arrays : Int
    timestamp_ms : UInt64
    // private fields
    }

    Counts physical dump records, not retained heap sizes or live-object proofs.

    Summary::array_values

    fn Summary::array_values(self : Summary, id : UInt64, offset? : Int, limit? : Int) -> Array[Value] raise ParseError

    Returns typed array elements without materializing the complete array.

    Summary::class_ids

    fn Summary::class_ids(self : Summary) -> Array[UInt64]

    Summary::class_info

    fn Summary::class_info(self : Summary, id : UInt64) -> ClassInfo?

    Summary::class_json

    fn Summary::class_json(self : Summary, id : UInt64) -> Json raise ParseError

    Summary::class_name

    fn Summary::class_name(self : Summary, id : UInt64) -> String?

    Summary::contains_object

    fn Summary::contains_object(self : Summary, id : UInt64) -> Bool

    Summary::count_class

    fn Summary::count_class(self : Summary, name : String) -> Int

    Summary::field

    fn Summary::field(self : Summary, id : UInt64, name : String, declaring_class? : UInt64) -> Value? raise ParseError

    Summary::file_size

    fn Summary::file_size(self : Summary) -> Int

    Summary::find_classes

    fn Summary::find_classes(self : Summary, name : String) -> Array[UInt64]

    Summary::gc_analysis

    fn Summary::gc_analysis(self : Summary, max_edges? : Int, max_slots? : Int) -> GCAnalysis raise ParseError

    Compute root reachability and immediate dominators using iterative dataflow. The implementation intentionally uses bounded reference indexing so malformed or unexpectedly large dumps fail rather than silently producing partial data.

    Summary::hierarchy

    fn Summary::hierarchy(self : Summary, class_id : UInt64) -> Array[ClassInfo] raise ParseError

    Most-derived class first: HPROF writes fields before inherited fields.

    Summary::histogram

    fn Summary::histogram(self : Summary) -> Array[HistogramRow] raise ParseError

    Summary::histogram_csv

    fn Summary::histogram_csv(self : Summary) -> String raise ParseError

    Summary::histogram_json

    fn Summary::histogram_json(self : Summary) -> Json raise ParseError

    Summary::instance_fields

    fn Summary::instance_fields(self : Summary, id : UInt64) -> Array[FieldValue] raise ParseError

    Summary::instance_payload_size

    fn Summary::instance_payload_size(self : Summary, class_id : UInt64) -> Int raise ParseError

    Summary::java_string

    fn Summary::java_string(self : Summary, id : UInt64, utf16_little_endian~ : Bool, max_chars? : Int) -> String raise ParseError

    Reads JDK char[] Strings and compact byte[] Strings with explicit byte order. HPROF does not encode the native byte order of compact UTF-16 String storage.

    Summary::largest_objects

    fn Summary::largest_objects(self : Summary, limit? : Int) -> Array[ObjectInfo] raise ParseError

    Summary::loader_statistics

    fn Summary::loader_statistics(self : Summary) -> Array[LoaderStatistics]

    Summary::object

    fn Summary::object(self : Summary, id : UInt64) -> ObjectInfo?

    Summary::object_count

    fn Summary::object_count(self : Summary) -> Int

    Summary::object_ids

    fn Summary::object_ids(self : Summary, class_id? : UInt64, offset? : Int, limit? : Int) -> Array[UInt64] raise ParseError

    IDs are sorted numerically for stable pagination. Zero denotes all classes.

    Summary::object_json

    fn Summary::object_json(self : Summary, id : UInt64, offset? : Int, limit? : Int) -> Json raise ParseError

    Exports one object; array pages include total length and requested offset.

    Summary::objects_jsonl

    fn Summary::objects_jsonl(self : Summary, class_id? : UInt64, offset? : Int, limit? : Int, array_limit? : Int) -> String raise ParseError

    Exports a bounded page as JSON Lines; each object is a separate JSON document. Arrays use their own item limit rather than expanding arbitrary-size payloads.

    Summary::payload

    fn Summary::payload(self : Summary, id : UInt64, offset? : Int, limit? : Int) -> Bytes raise ParseError

    Copies only the requested payload window; offsets are relative to payload.

    Summary::preview

    fn Summary::preview(self : Summary, id : UInt64, max_items? : Int, max_chars? : Int) -> ObjectPreview raise ParseError

    A one-level display: referenced objects are IDs and never recursively opened.

    Summary::previews_jsonl

    fn Summary::previews_jsonl(self : Summary, class_id? : UInt64, offset? : Int, limit? : Int, max_items? : Int, max_chars? : Int) -> String raise ParseError

    Summary::record_count

    fn Summary::record_count(self : Summary, tag : Int) -> Int

    Summary::references

    fn Summary::references(self : Summary, id : UInt64, limit? : Int) -> Array[ReferenceEdge] raise ParseError

    Field and array edges only. Null references are omitted.

    Summary::root_count

    fn Summary::root_count(self : Summary) -> Int

    Summary::root_kinds

    fn Summary::root_kinds(self : Summary) -> Map[String, Int]

    Summary::roots

    fn Summary::roots(self : Summary, offset? : Int, limit? : Int) -> Array[RootInfo] raise ParseError

    Summary::roots_for

    fn Summary::roots_for(self : Summary, id : UInt64) -> Array[RootInfo]

    Returns all matching GC roots. Multiple roots may refer to one object.

    Summary::select_histogram

    fn Summary::select_histogram(self : Summary, prefix? : String, kind? : String, sort? : HistogramSort, offset? : Int, limit? : Int) -> Array[HistogramRow] raise ParseError

    Filters by internal class name prefix and object kind before pagination.

    Summary::stack_frame

    fn Summary::stack_frame(self : Summary, id : UInt64) -> ResolvedFrame?

    Summary::stack_trace

    fn Summary::stack_trace(self : Summary, serial : UInt64) -> Array[ResolvedFrame] raise ParseError

    Summary::static_fields

    fn Summary::static_fields(self : Summary, class_id : UInt64) -> Array[FieldValue] raise ParseError

    Summary::string

    fn Summary::string(self : Summary, id : UInt64) -> String?

    Summary::summary_json

    fn Summary::summary_json(self : Summary) -> Json

    Summary::thread

    fn Summary::thread(self : Summary, serial : UInt64) -> ThreadInfo?

    Summary::thread_serials

    fn Summary::thread_serials(self : Summary) -> Array[UInt64]

    Summary::totals

    fn Summary::totals(self : Summary) -> HeapTotals

    Summary::trace_serials

    fn Summary::trace_serials(self : Summary) -> Array[UInt64]

    Summary::validate

    fn Summary::validate(self : Summary) -> Unit raise ParseError

    Checks class layouts and metadata references. Does not infer object liveness.

    ThreadInfo

    pub struct ThreadInfo {
    serial : UInt64
    object_id : UInt64
    stack_serial : UInt64
    name_id : UInt64
    group_name_id : UInt64
    parent_group_name_id : UInt64
    }

    Value

    pub enum Value {
    Reference(UInt64)
    Boolean(Bool)
    Character(Int)
    ByteValue(Int)
    ShortValue(Int)
    IntValue(Int)
    LongValue(Int64)
    FloatValue(Double)
    DoubleValue(Double)
    } derive(
    Debug
    )

    A typed HPROF value. Object IDs are kept as unsigned 64-bit integers.

    Value::display

    fn Value::display(self : Value) -> String

    Value::kind

    fn Value::kind(self : Value) -> Int

    Value::reference

    fn Value::reference(self : Value) -> UInt64?

    Value::to_json

    fn Value::to_json(self : Value) -> Json

    Value::to_repr

    cli_help

    fn cli_help() -> String

    compare_heaps

    fn compare_heaps(before : Summary, after : Summary) -> Array[HistogramDelta] raise ParseError

    Compares class-name aggregates. Object/loader IDs are not stable across dumps. This is a count comparison, not a claim that the same objects survived GC.

    csv_cell

    fn csv_cell(value : String) -> String

    RFC 4180 cell escaping. Newlines inside cells remain quoted data.

    decode_hprof_text

    fn decode_hprof_text(data : Bytes) -> String raise ParseError

    Decodes Java Modified UTF-8, also accepting canonical four-byte UTF-8. Unlike lossy decoding, invalid sequences never silently change identifiers.

    display_class_name

    fn display_class_name(name : String) -> String

    Converts a JVM array descriptor to a display name without changing identity.

    encode_hprof_text

    fn encode_hprof_text(text : String) -> Bytes

    Encodes Java Modified UTF-8, including two-byte NUL and surrogate pairs.

    execute

    fn execute(heap : Summary, arguments : Array[String]) -> String raise ParseError

    Pure command rendering: no process globals, filesystem, or console effects.

    field_descriptor

    fn field_descriptor(text : String) -> String raise ParseError

    Formats a field descriptor; void and trailing garbage are invalid.

    method_descriptor

    fn method_descriptor(text : String) -> MethodSignature raise ParseError

    Parses JVM method descriptors, excluding generic Signature attributes.

    parse

    fn parse(data : Bytes, limits? : ParseLimits) -> Summary raise ParseError

    Prototype for HotSpot JAVA PROFILE 1.0.2, with strict record boundaries. ponytail: retains the input and name tables; streaming/mmap is future work.

    parse_object_id

    fn parse_object_id(text : String) -> UInt64 raise ParseError

    parse_with_limits

    fn parse_with_limits(data : Bytes, limits : ParseLimits) -> Summary raise ParseError

    Parses and indexes a dump using explicit caller-specified resource limits.

    value_type_name

    fn value_type_name(kind : Int) -> String raise ParseError