pub struct GcWeak<T: GcNode> { /* private fields */ }Expand description
Weak reference
Implementations§
Source§impl<T: GcNode> GcWeak<T>
impl<T: GcNode> GcWeak<T>
pub fn version(&self) -> u16
Sourcepub fn upgrade<'a>(&self, heap: &'a GcHeap) -> Option<Gc<'a, T>>
pub fn upgrade<'a>(&self, heap: &'a GcHeap) -> Option<Gc<'a, T>>
Upgrade weak reference to strong reference
Examples found in repository?
examples/advanced_features.rs (line 92)
76fn demonstrate_weak_references(
77 heap: &mut GcHeap,
78 partition: gc_lite::GcPartitionId,
79) -> GcResult<()> {
80 println!("1. Create strong and weak references...");
81
82 let strong_ref =
83 unsafe { heap.alloc_root_raw(partition, MyString(String::from("Strong Reference Data"))) }
84 .map_err(|(err, _)| err)?;
85
86 let weak_ref = heap.downgrade(&strong_ref);
87 println!(" Created strong reference: {:?}", strong_ref);
88 println!(" Created weak reference: {:?}", weak_ref);
89
90 // Upgrade weak reference
91 println!("\n2. Upgrade weak reference...");
92 match weak_ref.upgrade(heap) {
93 Some(upgraded) => {
94 let data = &*upgraded;
95 println!(" Weak reference upgrade successful: '{}'", data);
96 assert_eq!(data, "Strong Reference Data");
97 }
98 None => println!(" Weak reference upgrade failed"),
99 }
100
101 // Try upgrading after releasing strong reference
102 println!("\n3. Upgrade weak reference after releasing strong reference...");
103 heap.garbage_collect(partition, GcHeap::DUMMY_DISPOSE_CALLBACK);
104
105 match weak_ref.upgrade(heap) {
106 Some(_) => {
107 println!(" Weak reference can still be upgraded (object may still be in memory)")
108 }
109 None => println!(" Weak reference upgrade failed (object has been collected)"),
110 }
111
112 Ok(())
113}More examples
examples/basic_usage.rs (line 169)
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}Trait Implementations§
impl<T: GcNode> Copy for GcWeak<T>
impl<T: PartialEq + GcNode> StructuralPartialEq for GcWeak<T>
Auto Trait Implementations§
impl<T> Freeze for GcWeak<T>
impl<T> RefUnwindSafe for GcWeak<T>where
T: RefUnwindSafe,
impl<T> Send for GcWeak<T>where
T: Send,
impl<T> Sync for GcWeak<T>where
T: Sync,
impl<T> Unpin for GcWeak<T>where
T: Unpin,
impl<T> UnsafeUnpin for GcWeak<T>
impl<T> UnwindSafe for GcWeak<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