OpenSimulator Internals/Walkthroughs/Garbage Collection
OpenSimulator Internals/Walkthroughs/Garbage Collection
[edit]Overview
[edit]Traces the two garbage collection mechanisms in OpenSimulator: temporary object cleanup (temp-on-rez objects expiring) and the periodic persistence/auto-return cycle (objects returned to owners for parcel violations). Also covers manual delete and the object persistence lifecycle.
1. Temporary Object Cleanup
[edit]OpenSim/Region/Framework/Scenes/Scene.cs -- CleanTempObjects()
Temporary objects are those with PrimFlags.TemporaryOnRez set. They expire based on a per-object Expires timestamp.
Trigger
[edit]CleanTempObjects() is called from the main heartbeat loop every m_update_temp_cleaning frames (default 180 frames, approximately every 16 seconds at ~11fps).
Runs asynchronously via WorkManager.RunInThreadPool to avoid blocking the heartbeat.
Process
[edit]- Gets all entities from scene graph.
- For each SceneObjectGroup:
- Checks IsDeleted.
- Checks RootPart.Flags has PrimFlags.TemporaryOnRez.
- Checks GetSittingAvatarsCount() == 0 -- does not expire objects with seated avatars.
- Checks RootPart.Expires <= DateTime.UtcNow.
- If all conditions met: calls DeleteSceneObject(grp, false).
DeleteSceneObject():
- Removes script instances.
- Removes physics actors.
- Unlinks from scene graph.
- Fires EventManager.TriggerObjectBeingRemovedFromScene().
- Calls SimulationDataService.RemoveObject() -- removes from prims/primshapes/primitems tables.
- DB writes
- prims -- DELETE
- primshapes -- DELETE
- primitems -- DELETE (task inventory)
Temporary objects are not saved to inventory. They simply disappear.
2. Periodic Object Persistence
[edit]OpenSim/Region/Framework/Scenes/Scene.cs -- UpdateStorageBackup() → Backup()
The region periodically persists changed objects to the database.
Trigger
[edit]UpdateStorageBackup() called every m_update_backup frames (default 200 frames, approximately every 18 seconds). Runs async via WorkManager.RunInThreadPool. Protected by m_backingup flag -- skips if previous backup still running.
Process
[edit]Backup() fires EventManager.TriggerOnBackup(SimulationDataService, forced).
The SimulationDataService handler iterates all SceneObjectGroups. For each group with HasGroupChanged = true:
Persistence timing check (unless forced=true):
- Must have been changed for at least MinimumTimeBeforePersistenceConsidered (default 60 seconds).
- Must not have been unchanged for longer than MaximumTimeBeforePersistenceConsidered (default 600 seconds) -- forces persistence of long-unchanged objects.
If conditions met: calls group.ProcessBackup(SimulationDataService, forced).
ProcessBackup() calls SimulationDataService.StoreObject():
- For each part in the group: writes to prims and primshapes tables (INSERT or UPDATE).
- Writes task inventory to primitems table.
- Clears HasGroupChanged.
- DB writes
- prims -- INSERT or UPDATE per changed prim
- primshapes -- INSERT or UPDATE
- primitems -- INSERT or UPDATE (task inventory)
Auto-Return Messages
[edit]Backup() also drains m_returns dictionary. For each returned object:
- Sends GridInstantMessage to the owner via IMessageTransferModule.
- Message: "Your object X was returned from parcel Y in region Z due to [reason]."
3. Parcel Auto-Return
[edit]Objects left on parcels they don't belong to are returned automatically based on parcel OtherCleanTime setting.
Trigger
[edit]ILandObject.ReturnLandObjects() is called periodically by the land module. Objects exceeding the parcel's OtherCleanTime are queued for return.
Process
[edit]- LandModule identifies objects that have exceeded their allowed time on the parcel.
- Calls Scene.returnObjects() with the list.
- returnObjects() calls IInventoryAccessModule.CopyToInventory(DeRezAction.Return) for each owner group.
- CopyBundleToInventory() serialises objects, creates assets, inserts inventory items into owner's Lost and Found folder.
- Scene.AddReturn() queues the return notification.
- Scene.DeleteSceneObject() removes objects from scene and database.
- DB writes
- assets -- INSERT: serialised object XML
- inventoryitems -- INSERT: item in Lost and Found
- prims/primshapes/primitems -- DELETE
4. Object Persistence Lifecycle Summary
[edit]| State | HasGroupChanged | In DB | Notes |
|---|---|---|---|
| Just rezzed | true | yes (immediately on AddNewSceneObject) | Immediately persisted on rez |
| Modified | true | stale | Queued for next backup cycle |
| Persisted | false | current | Written by Backup() |
| Temp-on-rez expired | -- | deleted | CleanTempObjects() removes |
| Deleted by avatar | -- | deleted | DeleteSceneObject() removes immediately |
| Returned | -- | deleted | CopyToInventory + DeleteSceneObject |
5. Shutdown Persistence
[edit]On Scene.Close():
- Calls Backup(true) with forced=true.
- All objects with HasGroupChanged = true are persisted regardless of timing.
- Ensures no changes are lost on clean shutdown.