Jump to content

OpenSimulator Internals/Walkthroughs/Garbage Collection

From Open Simulator Technical Help
Revision as of 22:38, 7 July 2026 by Jwbshaw (talk | contribs) (first)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

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]
  1. Gets all entities from scene graph.
  2. 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.
  3. 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]
  1. LandModule identifies objects that have exceeded their allowed time on the parcel.
  2. Calls Scene.returnObjects() with the list.
  3. returnObjects() calls IInventoryAccessModule.CopyToInventory(DeRezAction.Return) for each owner group.
  4. CopyBundleToInventory() serialises objects, creates assets, inserts inventory items into owner's Lost and Found folder.
  5. Scene.AddReturn() queues the return notification.
  6. 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.

See Also

[edit]