pub struct GcRef<T: GcNode> { /* private fields */ }Expand description
Garbage collection reference
Implementations§
Source§impl<T: GcNode> GcRef<T>
impl<T: GcNode> GcRef<T>
Sourcepub fn try_from_ref(heap: &GcHeap, data_ref: &T) -> Option<Self>
pub fn try_from_ref(heap: &GcHeap, data_ref: &T) -> Option<Self>
Create GcRef
This method verifies that the passed reference comes from a valid GC object. It ensures safety by checking if the corresponding GcHead is in the GC context.
§Parameters
data_ref: Reference to convert, must come from valid GcRef object
§Return Value
Some(GcRef<T>): If reference comes from valid GC objectNone: If reference is not from GC object or object is invalid
§Safety
Caller must ensure the passed reference indeed comes from a valid GcRef object.
Examples found in repository?
examples/advanced_features.rs (line 245)
222fn demonstrate_reference_recovery(
223 heap: &mut GcHeap,
224 partition: gc_lite::GcPartitionId,
225) -> GcResult<()> {
226 println!("1. Create object and get reference...");
227
228 let original_ref = unsafe {
229 heap.alloc_raw(
230 partition,
231 TestData {
232 value: 42,
233 name: "test".to_string(),
234 },
235 )
236 }
237 .map_err(|(err, _)| err)?;
238
239 let data_ref = original_ref.deref();
240 println!(" Original reference: {:?}", original_ref);
241 println!(" Data: {:?}", data_ref);
242
243 // Recover GcRef from reference
244 println!("\n2. Recover GcRef from reference...");
245 let recovered_ref = GcRef::try_from_ref(heap, data_ref);
246
247 match recovered_ref {
248 Some(recovered) => {
249 println!(" Recovery successful: {:?}", recovered);
250 let recovered_data = recovered.deref();
251 println!(" Recovered data: {:?}", recovered_data);
252 println!(" Data equal: {}", data_ref == recovered_data);
253 println!(" Reference equal: {}", original_ref == recovered);
254 }
255 None => println!(" Recovery failed (possibly type registration issue)"),
256 }
257
258 // Test invalid reference recovery - create an object not in GC heap
259 println!("\n3. Test invalid reference recovery...");
260 let local_data = TestData {
261 value: 100,
262 name: "local".to_string(),
263 };
264 let invalid_result = GcRef::try_from_ref(heap, &local_data);
265 println!(
266 " Invalid reference recovery result: {:?} (should be None)",
267 invalid_result
268 );
269
270 Ok(())
271}Sourcepub unsafe fn from_ref_unchecked(data_ref: &T) -> Self
pub unsafe fn from_ref_unchecked(data_ref: &T) -> Self
Unsafe conversion from &T to GcRef
§Safety
Caller must ensure &T comes from GcRef
Sourcepub fn with_mut<F, R>(&mut self, heap: &mut GcHeap, mutator: F) -> R
pub fn with_mut<F, R>(&mut self, heap: &mut GcHeap, mutator: F) -> R
Examples found in repository?
examples/advanced_features.rs (line 132)
118fn demonstrate_cyclic_references(
119 heap: &mut GcHeap,
120 partition: gc_lite::GcPartitionId,
121) -> GcResult<()> {
122 println!("1. Create circular reference nodes...");
123
124 // Create two mutually referencing nodes
125 let mut node1 = unsafe { heap.alloc_root_raw(partition, CyclicNode::new("Node A")) }
126 .map_err(|(err, _)| err)?;
127 let mut node2 = unsafe { heap.alloc_root_raw(partition, CyclicNode::new("Node B")) }
128 .map_err(|(err, _)| err)?;
129
130 // Establish circular references
131 {
132 node1.with_mut(heap, |n| n.set_partner(node2));
133 node2.with_mut(heap, |n| n.set_partner(node1));
134 }
135
136 println!(" Created node1: {}", node1.deref());
137 println!(" Created node2: {}", node2.deref());
138
139 // Trigger garbage collection
140 println!("\n2. Trigger garbage collection (circular references still exist)...");
141 let freed = heap.garbage_collect(partition, GcHeap::DUMMY_DISPOSE_CALLBACK);
142 println!(" 回收了 {} 字节内存", freed);
143
144 // Verify circular references still exist
145 println!("\n3. Verify circular references...");
146 println!(" Node1's partner: {}", node1.get_partner_name());
147 println!(" Node2's partner: {}", node2.get_partner_name());
148
149 // Clear root object status, let circular references be collected
150 println!("\n4. Clear root object status and trigger GC again...");
151 let freed = heap.garbage_collect(partition, GcHeap::DUMMY_DISPOSE_CALLBACK);
152 println!(
153 " Freed {} bytes of memory (circular references correctly collected)",
154 freed
155 );
156
157 Ok(())
158}
159
160/// Demonstrate complex data structures
161fn demonstrate_complex_structures(
162 heap: &mut GcHeap,
163 partition: gc_lite::GcPartitionId,
164) -> GcResult<()> {
165 println!("1. Create complex data structures...");
166
167 // Create multiple nodes
168 let mut root_node =
169 unsafe { heap.alloc_root_raw(partition, TreeNode::new("Root")) }.map_err(|(err, _)| err)?;
170 let mut child1 =
171 unsafe { heap.alloc_raw(partition, TreeNode::new("Child 1")) }.map_err(|(err, _)| err)?;
172 let child2 =
173 unsafe { heap.alloc_raw(partition, TreeNode::new("Child 2")) }.map_err(|(err, _)| err)?;
174 let grandchild = unsafe { heap.alloc_raw(partition, TreeNode::new("Grandchild")) }
175 .map_err(|(err, _)| err)?;
176
177 // Build tree structure
178 {
179 root_node.with_mut(heap, |n| n.add_child(child1));
180 root_node.with_mut(heap, |n| n.add_child(child2));
181 child1.with_mut(heap, |n| n.add_child(grandchild));
182 }
183
184 // Create data container
185 let container = unsafe {
186 heap.alloc_root_raw(
187 partition,
188 DataContainer {
189 root: root_node,
190 metadata: vec![1, 2, 3],
191 optional_data: Some(child1),
192 },
193 )
194 }
195 .map_err(|(err, _)| err)?;
196
197 println!(" Created tree structure:");
198 println!(" Root -> Child 1 -> Grandchild");
199 println!(" Root -> Child 2");
200 println!(" Created data container");
201
202 // Trigger garbage collection
203 println!("\n2. Trigger garbage collection...");
204 let freed = heap.garbage_collect(partition, GcHeap::DUMMY_DISPOSE_CALLBACK);
205 println!(" 回收了 {} 字节内存", freed);
206
207 // Verify data structure integrity
208 println!("\n3. Verify data structure integrity...");
209 {
210 println!(" Container root node: {}", container.root.name);
211 println!(" Metadata length: {}", container.metadata.len());
212 println!(
213 " Optional data exists: {}",
214 container.optional_data.is_some()
215 );
216 }
217
218 Ok(())
219}More examples
examples/performance_benchmark.rs (line 122)
88fn benchmark_complex_graphs() {
89 let sizes = [100, 500, 1000];
90
91 for &size in &sizes {
92 println!("\nTest complex object graph size: {} nodes", size);
93
94 let mut context = GcHeap::new(&GC_TYPE_REGISTRY);
95 let partition = context.create_partition();
96
97 // Create complex object graph
98 let graph_start = Instant::now();
99 let mut nodes = Vec::new();
100
101 // Create all nodes
102 for _i in 0..size {
103 let node = unsafe {
104 context.alloc_raw(
105 partition,
106 GraphNode {
107 neighbors: Vec::new(),
108 },
109 )
110 }
111 .unwrap();
112 nodes.push(node);
113 }
114
115 // Establish complex dependencies
116 for i in 0..size {
117 {
118 // Each node points to subsequent nodes
119 for j in 1..=5 {
120 if i + j < size {
121 let n = nodes[i + j];
122 nodes[i].with_mut(&mut context, |node| node.neighbors.push(n));
123 }
124 }
125 // Every 10 nodes form a cycle
126 if i % 10 == 0 && i + 9 < size {
127 let n = nodes[i];
128 nodes[i + 9].with_mut(&mut context, |node| node.neighbors.push(n));
129 }
130 }
131 }
132 let graph_duration = graph_start.elapsed();
133
134 println!(" Built complex object graph in: {:?}", graph_duration);
135
136 // Measure GC performance
137 let gc_start = Instant::now();
138 let freed = context.garbage_collect(partition, GcHeap::DUMMY_DISPOSE_CALLBACK);
139 let gc_duration = gc_start.elapsed();
140
141 println!(" GC回收 {} 字节耗时: {:?}", freed, gc_duration);
142 println!(
143 " Object graph complexity: average {} neighbors per node",
144 if size > 0 { (size * 5) / size } else { 0 }
145 );
146 }
147}examples/basic_usage.rs (line 192)
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}pub fn as_ptr(&self) -> NonNull<T>
pub fn downgrade(&self, heap: &mut GcHeap) -> GcWeak<T>
Sourcepub fn node_ptr(&self) -> NonNull<GcHead>
pub fn node_ptr(&self) -> NonNull<GcHead>
get node raw pointer
Examples found in repository?
examples/advanced_features.rs (line 305)
274fn demonstrate_cross_context_detection() -> GcResult<()> {
275 println!("1. Create two independent heaps...");
276
277 let mut heap1 = new_heap();
278 let mut heap2 = new_heap();
279
280 let partition1 = heap1.create_partition();
281 let partition2 = heap2.create_partition();
282
283 let obj1 = unsafe {
284 heap1.alloc_root_raw(
285 partition1,
286 TestData {
287 value: 1,
288 name: "obj1".to_string(),
289 },
290 )
291 }
292 .map_err(|(e, _)| e)?;
293 let obj2 = unsafe {
294 heap2.alloc_raw(
295 partition2,
296 TestData {
297 value: 2,
298 name: "obj2".to_string(),
299 },
300 )
301 }
302 .map_err(|(e, _)| e)?;
303
304 println!("2. Test object source detection...");
305 assert!(heap1.contains(obj1.node_ptr()), "obj1 should be from heap1");
306 assert!(
307 !heap1.contains(obj2.node_ptr()),
308 "obj2 should not be from heap1"
309 );
310 assert!(heap2.contains(obj2.node_ptr()), "obj2 should be from heap2");
311 assert!(
312 !heap2.contains(obj1.node_ptr()),
313 "obj1 should not be from heap2"
314 );
315
316 println!(" ✓ Cross-context detection correct");
317
318 // Clean up
319 heap1.garbage_collect(partition1, GcHeap::DUMMY_DISPOSE_CALLBACK);
320 heap2.garbage_collect(partition2, GcHeap::DUMMY_DISPOSE_CALLBACK);
321
322 Ok(())
323}Trait Implementations§
impl<T: GcNode> Copy for GcRef<T>
impl<T: GcNode> Eq for GcRef<T>
Auto Trait Implementations§
impl<T> Freeze for GcRef<T>
impl<T> RefUnwindSafe for GcRef<T>where
T: RefUnwindSafe,
impl<T> !Send for GcRef<T>
impl<T> !Sync for GcRef<T>
impl<T> Unpin for GcRef<T>where
T: Unpin,
impl<T> UnsafeUnpin for GcRef<T>
impl<T> UnwindSafe for GcRef<T>where
T: UnwindSafe,
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