Skip to content

Commit 78317b2

Browse files
author
Roberto De Ioris
authored
Update MemoryManagement.md
1 parent e0d2e0a commit 78317b2

File tree

1 file changed

+75
-0
lines changed

1 file changed

+75
-0
lines changed

docs/MemoryManagement.md

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,81 @@ print(factory)
7373
```
7474

7575
The RF_Standalone flag (RF_STANDALONE in python api) will marks a UObject as 'standalone' so it will remain resident in memory forever.
76+
77+
Eventually you can reset/set the flags:
78+
79+
```python
80+
import unreal_engine as ue
81+
82+
factory = BlueprintFactory()
83+
factory.set_obj_flags(ue.RF_PUBLIC|ue.RF_STANDALONE)
84+
85+
86+
ue.console_exec('obj gc')
87+
88+
print(factory)
89+
90+
# the second True argument will reset the flags (otherwise set_obj_flags will work in append mode)
91+
# eventually you can call factory.reset_obj_flags()
92+
factory.set_obj_flags(ue.RF_PUBLIC, True)
93+
94+
ue.console_exec('obj gc')
95+
96+
print(factory)
97+
```
98+
99+
The second print will raise the error.
100+
76101
This is a pretty raw approach (unless you are sure that you need a resident object). For having more control the second strategy will be way more better...
77102

78103
## Strategy 2: The Root Set
104+
105+
The root set is a very specific part of the GC tree. If you want to hold control of a UObject lifecycle in an efficient way, you can use the related python api:
106+
107+
```python
108+
import unreal_engine as ue
109+
110+
factory = BlueprintFactory()
111+
factory.add_to_root()
112+
113+
ue.console_exec('obj gc')
114+
115+
print(factory)
116+
117+
factory.remove_from_root()
118+
119+
ue.console_exec('obj gc')
120+
121+
print(factory)
122+
```
123+
124+
as before, the first GC run will not destroy the UObject (as it is in the root set), while the second one will remove if from the memory as it is no more in the root set.
125+
126+
A funny approach to memory management of UObject from python is by using a Tracker object:
127+
128+
```python
129+
class Tracker:
130+
131+
def __init__(self):
132+
self.uobjects = []
133+
134+
def track(self, uobject):
135+
uobject.add_to_root()
136+
self.uobjects.append(uobject)
137+
return uobject
138+
139+
def __del__(self):
140+
for uobject in self.uobjects:
141+
uobject.remove_from_root()
142+
143+
tracker = Tracker()
144+
```
145+
146+
Now you can create UObject from python and track them automatically. When the python GC destroys the tracker object, all of the UObject's tracked by it will be destroyed too:
147+
148+
```python
149+
factory = tracker.track(BlueprintFactory())
150+
```
151+
152+
As an example when running a script multiple times, the 'tracker' id will be overwritten, triggering the destruction of the mapped python object (and its __del__ method)
153+

0 commit comments

Comments
 (0)