Skip to main content

GcPartition

Struct GcPartition 

Source
pub struct GcPartition { /* private fields */ }

Implementations§

Source§

impl GcPartition

Source

pub fn nodes_mut(&mut self) -> NodeLinkIterMut<'_>

Source§

impl GcPartition

Source

pub fn memory_used(&self) -> usize

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

pub const fn is_marking(&self) -> bool

Trait Implementations§

Source§

impl Debug for GcPartition

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.