pub struct GcPartition { /* private fields */ }Implementations§
Source§impl GcPartition
impl GcPartition
Source§impl GcPartition
impl GcPartition
Sourcepub fn new(capacity: usize, max_alloc: usize) -> Self
pub fn new(capacity: usize, max_alloc: usize) -> Self
Create a new partition.
§Parameters
capacity: arena size in bytes.0= disable arena for this partition (all allocations go through system malloc directly).max_alloc: allocations larger than this skip the arena. Whencapacity == 0this is forced to0.
Sourcepub fn memory_used(&self) -> usize
pub fn memory_used(&self) -> usize
Examples found in repository?
examples/performance_benchmark.rs (line 173)
156fn benchmark_memory_efficiency() {
157 println!("\nTesting memory usage efficiency...");
158
159 let mut context = GcHeap::new(&GC_TYPE_REGISTRY);
160 context.set_memory_limit(1024 * 1024); // 1MB global limit
161 let partition = context.create_partition(64 * 1024, 16 * 1024);
162
163 // Allocate many small objects
164 let small_objects_count = 1000;
165 let mut small_objects = Vec::new();
166
167 for _i in 0..small_objects_count {
168 let obj = unsafe { context.alloc_raw(partition, SmallData {}) }.unwrap();
169 small_objects.push(obj);
170 }
171
172 if let Some(partition_info) = context.partition(partition) {
173 let used = partition_info.memory_used();
174 let limit = context.memory_limit();
175 let efficiency = if limit > 0 {
176 (used as f64 / limit as f64) * 100.0
177 } else {
178 0.0
179 };
180
181 println!(" After allocating {} small objects:", small_objects_count);
182 println!(
183 " Memory usage: {}/{} bytes ({:.1}%)",
184 used, limit, efficiency
185 );
186 println!(
187 " Average overhead per object: {} bytes",
188 if small_objects_count > 0 {
189 used / small_objects_count
190 } else {
191 0
192 }
193 );
194 }
195
196 // Collect all objects
197 let freed = context.garbage_collect(partition, GcHeap::DUMMY_DISPOSE_CALLBACK);
198 println!(" Collected all objects, freed {} bytes", freed);
199
200 // Verify complete memory collection
201 if let Some(partition_info) = context.partition(partition) {
202 let used_after = partition_info.memory_used();
203 println!(" Memory usage after collection: {} bytes", used_after);
204 println!(
205 " Memory collection rate: {:.1}%",
206 if freed > 0 {
207 (freed as f64 / (freed + used_after) as f64) * 100.0
208 } else {
209 0.0
210 }
211 );
212 }
213}
214
215/// Test automatic GC threshold performance
216fn benchmark_auto_gc_threshold() {
217 println!("\nTesting automatic GC threshold performance...");
218
219 let mut context = GcHeap::new(&GC_TYPE_REGISTRY);
220 context.set_memory_limit(2048); // 2KB global limit
221 let partition = context.create_partition(64 * 1024, 16 * 1024);
222
223 // Set automatic GC threshold to 1.5KB
224 context.set_gc_threshold(1500);
225
226 // Allocate objects until automatic GC is triggered
227 let mut allocated_bytes = 0;
228 let mut object_count = 0;
229
230 println!(" Allocating objects until automatic GC is triggered...");
231
232 for _i in 0..100 {
233 // Try at most 100 times
234 // Allocate objects of about 100 bytes
235 let node = SimpleNode {
236 _data: vec![0u8; 100],
237 };
238 match unsafe { context.alloc_raw(partition, node) } {
239 Ok(_gc_ref) => {
240 allocated_bytes += 100 + std::mem::size_of::<GcRef<SimpleNode>>(); // Estimated size
241 object_count += 1;
242
243 // Check if approaching threshold
244 if let Some(partition_info) = context.partition(partition)
245 && partition_info.memory_used() >= 1500
246 {
247 println!(
248 " Reached automatic GC threshold, allocated {} objects",
249 object_count
250 );
251 println!(" Estimated allocated memory: {} bytes", allocated_bytes);
252 println!(
253 " Actual memory usage: {} bytes",
254 partition_info.memory_used()
255 );
256 break;
257 }
258 }
259 Err(_) => {
260 println!(" Allocation failed, automatic GC may have been triggered");
261 break;
262 }
263 }
264 }
265
266 // Manually trigger GC to see effect
267 let freed = context.garbage_collect(partition, GcHeap::DUMMY_DISPOSE_CALLBACK);
268 println!(" Manual GC freed {} bytes", freed);
269}More examples
examples/basic_usage.rs (line 93)
47fn main() -> GcResult<()> {
48 println!("=== Basic usage example of partitioned garbage collection system ===");
49
50 // Create garbage collection context
51 let mut heap = GcHeap::new(&GC_TYPE_REGISTRY);
52
53 println!("Initial state:");
54 println!(" Number of partitions: {}", heap.partition_ids().len());
55
56 // Create two partitions
57 println!("\nCreate partitions:");
58 let partition1 = heap.create_partition(64 * 1024, 16 * 1024);
59 let partition2 = heap.create_partition(64 * 1024, 16 * 1024);
60 println!(" Created partition1: {:?}", partition1);
61 println!(" Created partition2: {:?}", partition2);
62 println!(" Number of partitions: {}", heap.partition_ids().len());
63
64 // Allocate objects in partition1
65 println!("\nAllocate objects in partition1:");
66 let obj1 = unsafe { heap.alloc_raw(partition1, MyString(String::from("Hello"))) }
67 .map_err(|(err, _)| err)?;
68 let obj2 = unsafe { heap.alloc_raw(partition1, MyI32(42)) }.map_err(|(err, _)| err)?;
69 let obj3 = unsafe { heap.alloc_raw(partition1, MyString(String::from("VectorData"))) }
70 .map_err(|(err, _)| err)?;
71
72 println!(" Created string: '{}'", unsafe { obj1.as_ref() });
73 println!(" Created number: {}", unsafe { obj2.as_ref() });
74 println!(" Created string: '{}'", unsafe { obj3.as_ref() });
75
76 // Allocate objects in partition2
77 println!("\nAllocate objects in partition2:");
78 let obj4 = unsafe { heap.alloc_raw(partition2, MyString(String::from("World"))) }
79 .map_err(|(err, _)| err)?;
80 let obj5 = unsafe { heap.alloc_raw(partition2, MyI32(99)) }.map_err(|(err, _)| err)?;
81
82 println!(" Created string: '{}'", unsafe { obj4.as_ref() });
83 println!(" Created number: {}", unsafe { obj5.as_ref() });
84
85 // Display partition status
86 println!("\nPartition status:");
87 for partition_id in heap.partition_ids() {
88 if let Some(partition) = heap.partition(partition_id) {
89 let limit = heap.memory_limit();
90 let usage = if limit > 0 {
91 format!(
92 "{}/{} bytes ({:.1}%)",
93 partition.memory_used(),
94 limit,
95 (partition.memory_used() as f64 / limit as f64) * 100.0
96 )
97 } else {
98 format!("{}/∞ bytes", partition.memory_used())
99 };
100 println!(
101 " {:?}: {} [自动GC: {}]",
102 partition_id,
103 usage,
104 if heap.gc_threshold() > 0 {
105 "Enabled"
106 } else {
107 "Disabled"
108 }
109 );
110 }
111 }
112
113 // Root objects are now implicitly managed by stack variables (e.g., obj1, obj2).
114 // No explicit `set_root` calls are needed for them.
115 println!("\nRoot objects are held by variables:");
116 println!(" Roots: obj1, obj2, obj3, obj4, obj5");
117
118 // Manually trigger garbage collection for partition1
119 println!("\nManually trigger garbage collection for partition1...");
120 let freed = heap.garbage_collect(partition1, GcHeap::DUMMY_DISPOSE_CALLBACK);
121 println!(" Collected {} bytes", freed);
122
123 // Verify root objects are still valid
124 println!("\nVerify partition1 root objects are still valid:");
125 println!(" Object1: '{}'", unsafe { obj1.as_ref() });
126 println!(" Object2: {}", unsafe { obj2.as_ref() });
127
128 // Manually trigger garbage collection for partition2
129 println!("\nManually trigger garbage collection for partition2...");
130 let freed = heap.garbage_collect(partition2, GcHeap::DUMMY_DISPOSE_CALLBACK);
131 println!(" Collected {} bytes", freed);
132
133 // Verify partition2 root objects are still valid
134 println!("\nVerify partition2 root objects are still valid:");
135 println!(" Object4: '{}'", unsafe { obj4.as_ref() });
136
137 // Trigger garbage collection for partition1 again to collect unreferenced objects
138 println!("\nTrigger garbage collection for partition1 again...");
139 // obj2 is no longer explicitly un-rooted, but we can simulate it going out of scope
140 // to test collection. For this example, we'll just collect other garbage.
141 let freed = heap.garbage_collect(partition1, GcHeap::DUMMY_DISPOSE_CALLBACK);
142 println!(" Collected {} bytes", freed);
143
144 // Verify remaining root objects are still valid
145 println!("\nVerify remaining root objects are still valid:");
146 println!(" Object1: '{}'", unsafe { obj1.as_ref() });
147 println!(" Object2: {} (still a root)", unsafe { obj2.as_ref() });
148
149 // Demonstrate automatic garbage collection
150 println!("\nDemonstrate automatic garbage collection...");
151
152 // Create a small partition to demonstrate automatic GC
153 let small_partition = heap.create_partition(64 * 1024, 16 * 1024);
154
155 // Allocate multiple objects to fill partition
156 for i in 0..5 {
157 let _obj = unsafe { heap.alloc_raw(small_partition, MyString(format!("Object {}", i))) }
158 .map_err(|(err, _)| err)?;
159 }
160
161 println!(" Allocated 5 objects in small partition");
162
163 // Demonstrate weak references
164 println!("\nDemonstrate weak references:");
165 let weak_ref = heap.downgrade(&obj1);
166 println!(" Created weak reference: {:?}", weak_ref);
167
168 // Upgrade weak reference
169 match weak_ref.upgrade(&heap) {
170 Some(strong_ref) => {
171 println!(" Weak reference upgrade successful: '{}'", &*strong_ref);
172 }
173 None => {
174 println!(" Weak reference upgrade failed");
175 }
176 }
177
178 // Demonstrate complex types with GC references
179 println!("\nDemonstrate complex types with GC references:");
180 let mut node1 =
181 unsafe { heap.alloc_raw(partition1, TestNode::new("Node 1")) }.map_err(|(err, _)| err)?;
182 let mut node2 =
183 unsafe { heap.alloc_raw(partition1, TestNode::new("Node 2")) }.map_err(|(err, _)| err)?;
184
185 // Establish references between nodes
186 {
187 unsafe {
188 node1.with_write_barrier(&mut heap, |n| n.add_child(node2));
189 }
190 unsafe {
191 node2.with_write_barrier(&mut heap, |n| n.add_child(node1));
192 }
193 }
194
195 println!(" Created node1: {}", unsafe { node1.as_ref() });
196 println!(" Created node2: {}", unsafe { node2.as_ref() });
197
198 // Trigger garbage collection, verify circular references are handled correctly
199 println!("\nGarbage collection for handling circular references...");
200 let freed = heap.garbage_collect(partition1, GcHeap::DUMMY_DISPOSE_CALLBACK);
201 println!(" 回收了 {} 字节内存", freed);
202
203 // Demonstrate partition deletion
204 println!("\nDemonstrate partition deletion:");
205
206 // Create an empty partition
207 let empty_partition = heap.create_partition(64 * 1024, 16 * 1024);
208 println!(" Created empty partition: {:?}", empty_partition);
209
210 // Delete empty partition
211 heap.remove_partition(empty_partition, GcHeap::DUMMY_DISPOSE_CALLBACK);
212 println!(" Deleted empty partition successfully");
213
214 // Delete non-empty partition
215 heap.remove_partition(partition1, GcHeap::DUMMY_DISPOSE_CALLBACK);
216 println!(" Deleted non-empty partition successfully");
217
218 println!("\nExample completed!");
219 Ok(())
220}pub const fn is_marking(&self) -> bool
Trait Implementations§
Auto Trait Implementations§
impl !Freeze for GcPartition
impl !RefUnwindSafe for GcPartition
impl !Send for GcPartition
impl !Sync for GcPartition
impl Unpin for GcPartition
impl UnsafeUnpin for GcPartition
impl UnwindSafe for GcPartition
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more