#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
pub struct HistRow {
pub pretty_class: String,
pub instances: u64,
pub shallow: u64,
pub retained: u64,
#[serde(default)]
pub max_instance_shallow: u64,
pub loader_id: u64,
pub loader_label: Option<String>,
}
#[derive(
Debug, Clone, Default, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema,
)]
pub struct UnreachableClassRow {
pub pretty_class: String,
pub objects: u64,
pub shallow: u64,
}
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
pub struct GcRootTypeRow {
pub root_type: String,
pub count: u64,
}
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
pub struct GcRootRetainedRow {
pub root_type: String,
pub count: u64,
pub retained: u64,
}
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
pub struct KindStat {
pub kind: String,
pub objects: u64,
pub shallow_heap: u64,
}
#[derive(
Debug, Clone, Default, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema,
)]
pub struct HeapComposition {
pub by_kind: Vec<KindStat>,
}
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
pub struct DepthBucket {
pub depth: u32,
pub objects: u64,
}
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
pub struct SizeBucket {
pub upper_bytes: u64,
pub count: u64,
}
#[derive(
Debug, Clone, Default, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema,
)]
pub struct TopSizeDistribution {
pub buckets: Vec<SizeBucket>,
pub count: u64,
pub min: u64,
pub max: u64,
pub median: u64,
pub total: u64,
}
#[derive(
Debug, Clone, Default, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema,
)]
pub struct RetentionSummary {
pub total_retained: u64,
pub top1_bp: u32,
pub top10_bp: u32,
pub top100_bp: u32,
pub num_objects_ge_1pct: u64,
}
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
pub struct PropEntry {
pub key: String,
pub value: String,
}
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
pub struct LoaderRollup {
pub loader_label: Option<String>,
pub loader_id: u64,
pub class_count: u64,
pub instances: u64,
pub shallow: u64,
pub retained: u64,
}
#[derive(
Debug, Clone, Default, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema,
)]
pub struct TopComponents {
pub components: Vec<Component>,
}
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
pub struct Component {
pub loader_label: String,
pub retained: u64,
pub pct: f64,
pub top_classes: Vec<ComponentClass>,
}
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
pub struct ComponentClass {
pub pretty_class: String,
pub retained: u64,
}
#[derive(
Debug, Clone, Default, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema,
)]
pub struct DuplicateClassLoaderRow {
pub loader_label: String,
pub loader_id: u64,
pub instances: u64,
pub shallow: u64,
pub retained: u64,
}
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
pub struct DuplicateClass {
pub pretty_class: String,
pub loader_count: u64,
pub loaders: Vec<String>,
pub total_instances: u64,
pub total_retained: u64,
#[serde(default)]
pub per_loader: Vec<DuplicateClassLoaderRow>,
}
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
pub struct SystemOverview {
pub source_name: String,
pub file_path: String,
pub format: String,
pub file_size: u64,
pub identifier_size_bits: u32,
pub compressed_oops: Option<bool>,
pub dump_creation: Option<i64>,
pub total_objects: u64,
pub total_shallow: u64,
pub gc_roots: u64,
pub gc_roots_by_type: Vec<GcRootTypeRow>,
pub heap_composition: HeapComposition,
pub dominator_depth_histogram: Vec<DepthBucket>,
pub retention_concentration: RetentionSummary,
pub classes_loaded: u64,
pub classloaders_loaded: u64,
pub unreachable_count: u64,
pub unreachable_shallow: u64,
#[serde(default)]
pub heap_fragmentation_ratio: f64,
#[serde(default)]
pub top_class_concentration_bp: u32,
#[serde(default)]
pub gc_roots_retained_by_type: Vec<GcRootRetainedRow>,
#[serde(default)]
pub unreachable_histogram: Vec<UnreachableClassRow>,
pub histogram: Vec<HistRow>,
pub histogram_truncated_to: Option<u64>,
pub system_properties: Vec<PropEntry>,
pub jvm_version: Option<String>,
pub loader_rollup: Vec<LoaderRollup>,
pub duplicate_classes: Vec<DuplicateClass>,
#[serde(default)]
pub record_census: crate::pass2::RecordCensus,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub duplicate_strings: Option<crate::pass2::DupStrings>,
}
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
pub struct PathStep {
pub depth: usize,
pub obj_index_1based: usize,
pub display_class: String,
pub retained: u64,
}
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
pub struct RootPathStep {
pub obj_index_1based: usize,
pub display_class: String,
pub retained: u64,
#[serde(skip_serializing_if = "Option::is_none")]
pub root_type_label: Option<String>,
}
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
pub struct DominatedRow {
pub obj_index_1based: usize,
pub display_class: String,
pub shallow: u64,
pub retained: u64,
}
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
pub struct DomTreeNode {
pub obj_index_1based: usize,
pub display_class: String,
pub shallow: u64,
pub retained: u64,
pub children: Vec<DomTreeNode>,
}
#[derive(
Debug, Clone, Default, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema,
)]
pub struct MergedPathNode {
pub display_class: String,
pub object_count: u64,
pub retained: u64,
#[serde(skip_serializing_if = "Option::is_none")]
pub root_type_label: Option<String>,
pub children: Vec<MergedPathNode>,
}
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
pub struct Suspect {
pub is_single: bool,
pub pretty_class: String,
pub instance_count: u64,
pub retained: u64,
pub shallow: u64,
pub path: Vec<PathStep>,
pub accumulation_obj_1based: Option<usize>,
pub accumulation_class: Option<String>,
pub accumulation_retained: Option<u64>,
pub dominated: Vec<DominatedRow>,
pub dominated_total_count: u64,
pub dominated_shown: u64,
pub dominated_by_class: Vec<HistRow>,
pub keywords: Vec<String>,
pub root_type_label: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub root_path: Option<Vec<RootPathStep>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub dominator_tree: Option<DomTreeNode>,
#[serde(skip_serializing_if = "Option::is_none")]
pub merged_paths: Option<MergedPathNode>,
}
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
pub struct LeakSuspects {
pub total_shallow: u64,
pub suspects: Vec<Suspect>,
}
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
pub struct ObjRow {
pub obj_index_1based: usize,
pub display_class: String,
pub shallow: u64,
pub retained: u64,
pub pct_bp: u64,
#[serde(skip)]
#[schemars(skip)]
pub pct: f64,
}
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
pub struct ClassRow {
pub pretty_class: String,
pub instances: u64,
pub retained: u64,
}
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
pub struct PackageNode {
pub name: String,
pub top_dominator_count: u64,
pub shallow_heap: u64,
pub retained_heap: u64,
pub children: Vec<PackageNode>,
}
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
pub struct TopConsumers {
pub biggest_objects: Vec<ObjRow>,
pub biggest_classes: Vec<ClassRow>,
pub threshold_bp: u32,
pub biggest_packages: PackageNode,
#[serde(default)]
pub size_distribution: TopSizeDistribution,
}
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
pub struct ThreadInfo {
pub thread_serial: u32,
pub name: Option<String>,
pub class_name: Option<String>,
pub frames: Vec<String>,
pub local_root_count: u64,
#[serde(skip_serializing_if = "Option::is_none")]
pub local_objects: Option<Vec<ThreadLocalObj>>,
#[serde(default)]
pub shallow: u64,
#[serde(default)]
pub retained: u64,
#[serde(default)]
pub max_local_retained: u64,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub context_class_loader: Option<String>,
#[serde(default)]
pub is_daemon: bool,
#[serde(default)]
pub priority: i32,
#[serde(default)]
pub thread_state: String,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub significant_frames: Vec<SignificantFrame>,
}
#[derive(
Debug, Clone, Default, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema,
)]
pub struct SignificantFrame {
pub frame: String,
pub locals: Vec<SignificantLocal>,
}
#[derive(
Debug, Clone, Default, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema,
)]
pub struct SignificantLocal {
pub display_class: String,
pub retained: u64,
pub pct: f64,
}
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
pub struct ThreadLocalObj {
pub obj_index_1based: usize,
pub display_class: String,
pub shallow: u64,
pub retained: u64,
}
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
pub struct ThreadOverview {
pub threads: Vec<ThreadInfo>,
}
#[derive(
Debug, Clone, Default, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema,
)]
pub struct SizeHistogramBucket {
pub upper_len: u64,
pub objects: u64,
pub shallow: u64,
}
#[derive(
Debug, Clone, Default, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema,
)]
pub struct ArraysBySize {
pub obj_array_buckets: Vec<SizeHistogramBucket>,
pub prim_array_buckets: Vec<SizeHistogramBucket>,
pub zero_length_count: u64,
}
#[derive(
Debug, Clone, Default, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema,
)]
pub struct BigDropRow {
pub obj_index_1based: u64,
pub display_class: String,
pub retained: u64,
pub child_count: u64,
pub largest_child_retained: u64,
pub largest_child_class: String,
pub drop_bytes: u64,
}
#[derive(
Debug, Clone, Default, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema,
)]
pub struct BigDrops {
pub threshold: u64,
pub rows: Vec<BigDropRow>,
}
#[derive(
Debug, Clone, Default, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema,
)]
pub struct ImmediateDominatorRow {
pub dominator_class: String,
pub dominator_count: u64,
pub dominated_count: u64,
pub dominator_shallow: u64,
pub dominated_shallow: u64,
}
#[derive(
Debug, Clone, Default, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema,
)]
pub struct ImmediateDominators {
pub rows: Vec<ImmediateDominatorRow>,
}
#[derive(
Debug, Clone, Default, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema,
)]
pub struct DominatorAnalysis {
pub big_drops: BigDrops,
pub immediate_dominators: ImmediateDominators,
}
#[derive(
Debug, Clone, Default, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema,
)]
pub struct FillRatioBucket {
pub lower_ratio_bp: u32,
pub upper_ratio_bp: u32,
pub objects: u64,
pub shallow: u64,
pub wasted: u64,
}
#[derive(
Debug, Clone, Default, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema,
)]
pub struct CollectionFillRatio {
pub tracked: u64,
pub total: u64,
pub buckets: Vec<FillRatioBucket>,
}
#[derive(
Debug, Clone, Default, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema,
)]
pub struct CollectionsBySize {
pub tracked: u64,
pub empty_count: u64,
pub buckets: Vec<SizeHistogramBucket>,
}
#[derive(
Debug, Clone, Default, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema,
)]
pub struct ArrayFillRatio {
pub tracked: u64,
pub buckets: Vec<FillRatioBucket>,
}
#[derive(
Debug, Clone, Default, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema,
)]
pub struct MapCollisionRatio {
pub tracked: u64,
pub total: u64,
pub buckets: Vec<FillRatioBucket>,
}
#[derive(
Debug, Clone, Default, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema,
)]
pub struct ConstantArrayRow {
pub array_class: String,
pub length: u64,
pub value: i64,
pub objects: u64,
pub shallow: u64,
}
#[derive(
Debug, Clone, Default, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema,
)]
pub struct ConstantPrimitiveArrays {
pub rows: Vec<ConstantArrayRow>,
pub truncated: bool,
}
#[derive(
Debug, Clone, Default, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema,
)]
pub struct TopArrayRow {
pub array_class: String,
pub length: u64,
pub shallow: u64,
pub obj_index_1based: u64,
#[serde(default)]
pub owner: Option<String>,
}
#[derive(
Debug, Clone, Default, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema,
)]
pub struct TopArrayClassRow {
pub array_class: String,
pub objects: u64,
pub shallow: u64,
}
#[derive(
Debug, Clone, Default, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema,
)]
pub struct TopArrays {
pub top_individual: Vec<TopArrayRow>,
pub top_by_class: Vec<TopArrayClassRow>,
}
#[derive(
Debug, Clone, Default, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema,
)]
pub struct CollectionsAnalysis {
#[serde(default)]
pub collection_fill_ratio: CollectionFillRatio,
#[serde(default)]
pub collections_by_size: CollectionsBySize,
#[serde(default)]
pub array_fill_ratio: ArrayFillRatio,
#[serde(default)]
pub map_collision_ratio: MapCollisionRatio,
#[serde(default)]
pub constant_primitive_arrays: ConstantPrimitiveArrays,
#[serde(default)]
pub top_prim_arrays: TopArrays,
#[serde(default)]
pub top_obj_arrays: TopArrays,
#[serde(default)]
pub kind_summary: CollectionKindSummary,
}
#[derive(
Debug, Clone, Default, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema,
)]
pub struct CollectionKindStat {
pub kind: String, pub count: u64, pub total_elements: u64, pub total_shallow: u64, pub max_elements: u64, }
#[derive(
Debug, Clone, Default, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema,
)]
pub struct CollectionKindSummary {
pub kinds: Vec<CollectionKindStat>,
}
#[derive(
Debug, Clone, Default, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema,
)]
pub struct FieldAttributionRow {
pub holder_class: String,
pub field: String,
pub container_kind: String,
pub total_elements: u64,
pub total_retained: u64,
pub container_count: u64,
#[serde(default)]
pub holder_instances: u64,
}
#[derive(
Debug, Clone, Default, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema,
)]
pub struct FieldAttributionBiggestRow {
pub holder_class: String,
pub field: String,
pub container_class: String,
pub elements: u64,
pub retained: u64,
#[serde(default)]
pub capacity: u64,
}
#[derive(
Debug, Clone, Default, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema,
)]
pub struct CollectionAttribution {
pub most_overall: Vec<FieldAttributionRow>,
pub biggest_single: Vec<FieldAttributionBiggestRow>,
pub truncated: bool,
}
#[derive(
Debug, Clone, Default, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema,
)]
pub struct FieldBySizeRow {
pub holder_class: String,
pub field: String,
pub pointee_type: String,
pub total_retained: u64,
pub pointees: u64,
pub holder_instances: u64,
#[serde(default)]
pub elements: u64,
#[serde(default)]
pub category: String,
}
#[derive(
Debug, Clone, Default, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema,
)]
pub struct FieldsBySize {
pub rows: Vec<FieldBySizeRow>,
pub truncated: bool,
}
#[derive(
Debug, Clone, Default, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema,
)]
pub struct ValueTypeShare {
pub type_name: String,
pub count: u64,
}
#[derive(
Debug, Clone, Default, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema,
)]
pub struct BiggestCollectionRow {
pub kind: String,
pub container_class: String,
pub elements: u64,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub retained: Option<u64>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub owner: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub dominant_value_type: Option<String>,
#[serde(default)]
pub value_type_breakdown: Vec<ValueTypeShare>,
}
#[derive(
Debug, Clone, Default, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema,
)]
pub struct CollectionKindTable {
pub kind: String,
pub rows: Vec<BiggestCollectionRow>,
}
#[derive(
Debug, Clone, Default, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema,
)]
pub struct BiggestCollections {
pub combined: Vec<BiggestCollectionRow>,
pub by_kind: Vec<CollectionKindTable>,
pub truncated: bool,
}
#[derive(
Debug, Clone, Default, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema,
)]
pub struct CollectionContentsRow {
pub collection_class: String,
pub instances: u64,
pub total_values: u64,
pub top_value_types: Vec<ValueTypeShare>,
}
#[derive(
Debug, Clone, Default, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema,
)]
pub struct CollectionContents {
pub rows: Vec<CollectionContentsRow>,
pub truncated: bool,
}
#[derive(
Debug, Clone, Default, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema,
)]
pub struct RefStatClassRow {
pub pretty_class: String,
pub objects: u64,
pub shallow: u64,
}
#[derive(
Debug, Clone, Default, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema,
)]
pub struct ReferenceStats {
pub kind: String,
pub reference_instances: u64,
pub referent_histogram: Vec<RefStatClassRow>,
pub only_weakly_retained: Vec<RefStatClassRow>,
}
#[derive(
Debug, Clone, Default, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema,
)]
pub struct ReferencesAnalysis {
#[serde(default)]
pub soft: Option<ReferenceStats>,
#[serde(default)]
pub weak: Option<ReferenceStats>,
#[serde(default)]
pub phantom: Option<ReferenceStats>,
}
#[derive(
Debug, Clone, Default, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema,
)]
pub struct LeakIndicators {
pub anonymous_class_count: u64,
pub thread_local_null_key_count: u64,
pub direct_byte_buffer_capacity_sum: u64,
}
pub const SCHEMA_VERSION: u32 = 3;
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
pub struct AllocSite {
pub stack_serial: u32,
pub frames: Vec<String>,
pub object_count: u64,
pub shallow_total: u64,
pub retained_total: u64,
}
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
pub struct AllocSites {
pub traces_present: bool,
pub sites: Vec<AllocSite>,
}
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
pub struct Report {
pub schema_version: u32,
pub generated: String,
pub overview: SystemOverview,
pub leaks: LeakSuspects,
pub top: TopConsumers,
pub threads: ThreadOverview,
#[serde(default)]
pub top_components: TopComponents,
#[serde(skip_serializing_if = "Option::is_none")]
pub alloc_sites: Option<AllocSites>,
#[serde(default)]
pub arrays_by_size: ArraysBySize,
#[serde(default)]
pub dominator_analysis: DominatorAnalysis,
#[serde(default)]
pub collections: CollectionsAnalysis,
#[serde(default)]
pub references: ReferencesAnalysis,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub collection_attribution: Option<CollectionAttribution>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub fields_by_size: Option<FieldsBySize>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub biggest_collections: Option<BiggestCollections>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub collection_contents: Option<CollectionContents>,
#[serde(default)]
pub leak_indicators: LeakIndicators,
}