memscope_rs/capture/types/
fragmentation.rs1use serde::{Deserialize, Serialize};
7
8use super::allocation::ImpactLevel;
9
10#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
12pub struct EnhancedFragmentationAnalysis {
13 pub total_heap_size: usize,
15 pub used_heap_size: usize,
17 pub free_heap_size: usize,
19 pub free_block_count: usize,
21 pub free_block_distribution: Vec<BlockSizeRange>,
23 pub fragmentation_metrics: FragmentationMetrics,
25 pub fragmentation_causes: Vec<FragmentationCause>,
27}
28
29#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
31pub struct BlockSizeRange {
32 pub min_size: usize,
34 pub max_size: usize,
36 pub block_count: usize,
38 pub total_size: usize,
40}
41
42#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
44pub struct FragmentationMetrics {
45 pub external_fragmentation: f64,
47 pub internal_fragmentation: f64,
49 pub largest_free_block: usize,
51 pub average_free_block_size: f64,
53 pub severity_level: FragmentationSeverity,
55}
56
57#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
59pub enum FragmentationSeverity {
60 Low,
62 Moderate,
64 High,
66 Critical,
68}
69
70#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
72pub struct FragmentationCause {
73 pub cause_type: FragmentationCauseType,
75 pub description: String,
77 pub impact_level: ImpactLevel,
79 pub mitigation_suggestion: String,
81}
82
83#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
85pub enum FragmentationCauseType {
86 MixedAllocationSizes,
88 FrequentAllocDealloc,
90 LongLivedAllocations,
92 PoorAllocationStrategy,
94 MemoryLeaks,
96}
97
98impl From<crate::core::types::EnhancedFragmentationAnalysis> for EnhancedFragmentationAnalysis {
100 fn from(old: crate::core::types::EnhancedFragmentationAnalysis) -> Self {
101 Self {
102 total_heap_size: old.total_heap_size,
103 used_heap_size: old.used_heap_size,
104 free_heap_size: old.free_heap_size,
105 free_block_count: old.free_block_count,
106 free_block_distribution: old
107 .free_block_distribution
108 .into_iter()
109 .map(|b| BlockSizeRange {
110 min_size: b.min_size,
111 max_size: b.max_size,
112 block_count: b.block_count,
113 total_size: b.total_size,
114 })
115 .collect(),
116 fragmentation_metrics: FragmentationMetrics {
117 external_fragmentation: old.fragmentation_metrics.external_fragmentation,
118 internal_fragmentation: old.fragmentation_metrics.internal_fragmentation,
119 largest_free_block: old.fragmentation_metrics.largest_free_block,
120 average_free_block_size: old.fragmentation_metrics.average_free_block_size,
121 severity_level: match old.fragmentation_metrics.severity_level {
122 crate::core::types::FragmentationSeverity::Low => FragmentationSeverity::Low,
123 crate::core::types::FragmentationSeverity::Moderate => {
124 FragmentationSeverity::Moderate
125 }
126 crate::core::types::FragmentationSeverity::High => FragmentationSeverity::High,
127 crate::core::types::FragmentationSeverity::Critical => {
128 FragmentationSeverity::Critical
129 }
130 },
131 },
132 fragmentation_causes: old
133 .fragmentation_causes
134 .into_iter()
135 .map(|c| FragmentationCause {
136 cause_type: match c.cause_type {
137 crate::core::types::FragmentationCauseType::MixedAllocationSizes => {
138 FragmentationCauseType::MixedAllocationSizes
139 }
140 crate::core::types::FragmentationCauseType::FrequentAllocDealloc => {
141 FragmentationCauseType::FrequentAllocDealloc
142 }
143 crate::core::types::FragmentationCauseType::LongLivedAllocations => {
144 FragmentationCauseType::LongLivedAllocations
145 }
146 crate::core::types::FragmentationCauseType::PoorAllocationStrategy => {
147 FragmentationCauseType::PoorAllocationStrategy
148 }
149 crate::core::types::FragmentationCauseType::MemoryLeaks => {
150 FragmentationCauseType::MemoryLeaks
151 }
152 },
153 description: c.description,
154 impact_level: match c.impact_level {
155 crate::core::types::ImpactLevel::Low => ImpactLevel::Low,
156 crate::core::types::ImpactLevel::Medium => ImpactLevel::Medium,
157 crate::core::types::ImpactLevel::High => ImpactLevel::High,
158 crate::core::types::ImpactLevel::Critical => ImpactLevel::Critical,
159 },
160 mitigation_suggestion: c.mitigation_suggestion,
161 })
162 .collect(),
163 }
164 }
165}
166
167#[cfg(test)]
168mod tests {
169 use super::*;
170
171 #[test]
172 fn test_enhanced_fragmentation_analysis() {
173 let analysis = EnhancedFragmentationAnalysis {
174 total_heap_size: 1024 * 1024,
175 used_heap_size: 512 * 1024,
176 free_heap_size: 512 * 1024,
177 free_block_count: 10,
178 free_block_distribution: vec![],
179 fragmentation_metrics: FragmentationMetrics {
180 external_fragmentation: 0.3,
181 internal_fragmentation: 0.1,
182 largest_free_block: 256 * 1024,
183 average_free_block_size: 51200.0,
184 severity_level: FragmentationSeverity::Low,
185 },
186 fragmentation_causes: vec![],
187 };
188
189 assert_eq!(analysis.total_heap_size, 1024 * 1024);
190 assert_eq!(analysis.free_block_count, 10);
191 }
192
193 #[test]
194 fn test_fragmentation_severity() {
195 let severity = FragmentationSeverity::High;
196 assert!(matches!(severity, FragmentationSeverity::High));
197 }
198
199 #[test]
200 fn test_fragmentation_cause_type() {
201 let cause = FragmentationCauseType::MixedAllocationSizes;
202 assert!(matches!(
203 cause,
204 FragmentationCauseType::MixedAllocationSizes
205 ));
206 }
207}