<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>http://osimdev.org/wiki/index.php?action=history&amp;feed=atom&amp;title=OpenSimulator_Internals%2FWalkthroughs%2FGarbage_Collection</id>
	<title>OpenSimulator Internals/Walkthroughs/Garbage Collection - Revision history</title>
	<link rel="self" type="application/atom+xml" href="http://osimdev.org/wiki/index.php?action=history&amp;feed=atom&amp;title=OpenSimulator_Internals%2FWalkthroughs%2FGarbage_Collection"/>
	<link rel="alternate" type="text/html" href="http://osimdev.org/wiki/index.php?title=OpenSimulator_Internals/Walkthroughs/Garbage_Collection&amp;action=history"/>
	<updated>2026-08-04T15:31:29Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.45.3</generator>
	<entry>
		<id>http://osimdev.org/wiki/index.php?title=OpenSimulator_Internals/Walkthroughs/Garbage_Collection&amp;diff=102&amp;oldid=prev</id>
		<title>Jwbshaw: first</title>
		<link rel="alternate" type="text/html" href="http://osimdev.org/wiki/index.php?title=OpenSimulator_Internals/Walkthroughs/Garbage_Collection&amp;diff=102&amp;oldid=prev"/>
		<updated>2026-07-07T22:38:02Z</updated>

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