aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region
diff options
context:
space:
mode:
authorMelanie2009-08-06 22:03:20 +0100
committerMelanie2009-08-06 22:03:20 +0100
commit91f6898b26caa8f74533dbd90478cf4103251abe (patch)
tree0ee8d1b94c3f0667d32cbf56043fd021fc8d8b73 /OpenSim/Region
parentMerge branch 'master' of ssh://melanie@opensimulator.org/var/git/opensim (diff)
downloadopensim-SC_OLD-91f6898b26caa8f74533dbd90478cf4103251abe.zip
opensim-SC_OLD-91f6898b26caa8f74533dbd90478cf4103251abe.tar.gz
opensim-SC_OLD-91f6898b26caa8f74533dbd90478cf4103251abe.tar.bz2
opensim-SC_OLD-91f6898b26caa8f74533dbd90478cf4103251abe.tar.xz
|From: James J Greensky <jame.j.greensky@intel.com>
|Date: Wed, 5 Aug 2009 09:51:52 -0700 |Subject: [PATCH] Closed two major memory leaks for scripted objects | |Two major memory leaks for the scripted objects were fixed |- One leak had to do with remoting acrossing app domains. When a script and | its controlling agent communicate across an application boundary, it calls | functions on a stub proxy object that then invokes the remote method on | the object in the other app domain. These stub objects (two for each script) | were setup to have infinate lifetimes and were never being garbage collected. |- The second leak was the result of adding a scene object part instance method | to a scene event and never removing it. This cause the event's delegate list | to maintain a link to that object which is then never freed as the scene event | object is never destroyed. Patch applied, please direct feedback to me. Possible issue: Longtime idle scripts like vendors may fail.
Diffstat (limited to 'OpenSim/Region')
-rw-r--r--OpenSim/Region/Framework/Scenes/EventManager.cs11
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs16
-rw-r--r--OpenSim/Region/ScriptEngine/Interfaces/IScript.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs5
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs7
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs22
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs25
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptSponsor.cs12
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs25
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/XEngine.cs14
11 files changed, 73 insertions, 68 deletions
diff --git a/OpenSim/Region/Framework/Scenes/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs
index 086496e..1d4d6d7 100644
--- a/OpenSim/Region/Framework/Scenes/EventManager.cs
+++ b/OpenSim/Region/Framework/Scenes/EventManager.cs
@@ -953,11 +953,12 @@ namespace OpenSim.Region.Framework.Scenes
953 // this lets us keep track of nasty script events like timer, etc. 953 // this lets us keep track of nasty script events like timer, etc.
954 public void TriggerTimerEvent(uint objLocalID, double Interval) 954 public void TriggerTimerEvent(uint objLocalID, double Interval)
955 { 955 {
956 handlerScriptTimerEvent = OnScriptTimerEvent; 956 throw new NotImplementedException("TriggerTimerEvent was thought to be not used anymore and the registration for the event from scene object part has been commented out due to a memory leak");
957 if (handlerScriptTimerEvent != null) 957 //handlerScriptTimerEvent = OnScriptTimerEvent;
958 { 958 //if (handlerScriptTimerEvent != null)
959 handlerScriptTimerEvent(objLocalID, Interval); 959 //{
960 } 960 // handlerScriptTimerEvent(objLocalID, Interval);
961 //}
961 } 962 }
962 963
963 /// <summary> 964 /// <summary>
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index bc11709..61dfa52 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -3673,14 +3673,14 @@ if (m_shape != null) {
3673 return; 3673 return;
3674 } 3674 }
3675 3675
3676 if ((GetEffectiveObjectFlags() & (uint)PrimFlags.Scripted) != 0) 3676 //if ((GetEffectiveObjectFlags() & (uint)PrimFlags.Scripted) != 0)
3677 { 3677 //{
3678 m_parentGroup.Scene.EventManager.OnScriptTimerEvent += handleTimerAccounting; 3678 // m_parentGroup.Scene.EventManager.OnScriptTimerEvent += handleTimerAccounting;
3679 } 3679 //}
3680 else 3680 //else
3681 { 3681 //{
3682 m_parentGroup.Scene.EventManager.OnScriptTimerEvent -= handleTimerAccounting; 3682 // m_parentGroup.Scene.EventManager.OnScriptTimerEvent -= handleTimerAccounting;
3683 } 3683 //}
3684 3684
3685 LocalFlags=(PrimFlags)objectflagupdate; 3685 LocalFlags=(PrimFlags)objectflagupdate;
3686 3686
diff --git a/OpenSim/Region/ScriptEngine/Interfaces/IScript.cs b/OpenSim/Region/ScriptEngine/Interfaces/IScript.cs
index b9618d1..726dabc 100644
--- a/OpenSim/Region/ScriptEngine/Interfaces/IScript.cs
+++ b/OpenSim/Region/ScriptEngine/Interfaces/IScript.cs
@@ -41,5 +41,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
41 Dictionary<string,Object> GetVars(); 41 Dictionary<string,Object> GetVars();
42 void SetVars(Dictionary<string,Object> vars); 42 void SetVars(Dictionary<string,Object> vars);
43 void ResetVars(); 43 void ResetVars();
44
45 void Close();
44 } 46 }
45} 47}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index bc36fda..5f9b09b 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -119,14 +119,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
119 AsyncCommands = new AsyncCommandManager(ScriptEngine); 119 AsyncCommands = new AsyncCommandManager(ScriptEngine);
120 } 120 }
121 121
122 // Object never expires
123 public override Object InitializeLifetimeService() 122 public override Object InitializeLifetimeService()
124 { 123 {
125 ILease lease = (ILease)base.InitializeLifetimeService(); 124 ILease lease = (ILease)base.InitializeLifetimeService();
126 125
127 if (lease.CurrentState == LeaseState.Initial) 126 if (lease.CurrentState == LeaseState.Initial)
128 { 127 {
129 lease.InitialLeaseTime = TimeSpan.Zero; 128 lease.InitialLeaseTime = TimeSpan.FromMinutes(1.0);
129 lease.RenewOnCallTime = TimeSpan.FromSeconds(10.0);
130 lease.SponsorshipTimeout = TimeSpan.FromMinutes(1.0);
130 } 131 }
131 return lease; 132 return lease;
132 } 133 }
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index 7c878b8..b447cfb 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -159,16 +159,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
159 } 159 }
160 } 160 }
161 161
162 //
163 // Never expire this object
164 //
165 public override Object InitializeLifetimeService() 162 public override Object InitializeLifetimeService()
166 { 163 {
167 ILease lease = (ILease)base.InitializeLifetimeService(); 164 ILease lease = (ILease)base.InitializeLifetimeService();
168 165
169 if (lease.CurrentState == LeaseState.Initial) 166 if (lease.CurrentState == LeaseState.Initial)
170 { 167 {
171 lease.InitialLeaseTime = TimeSpan.Zero; 168 lease.InitialLeaseTime = TimeSpan.FromMinutes(1.0);
169 lease.RenewOnCallTime = TimeSpan.FromSeconds(10.0);
170 lease.SponsorshipTimeout = TimeSpan.FromMinutes(1.0);
172 } 171 }
173 return lease; 172 return lease;
174 } 173 }
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs
index 2501752..7f67599 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs
@@ -35,7 +35,7 @@ using log4net;
35 35
36namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase 36namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
37{ 37{
38 public class Executor : MarshalByRefObject 38 public class Executor
39 { 39 {
40 // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 40 // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
41 41
@@ -89,26 +89,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
89 initEventFlags(); 89 initEventFlags();
90 } 90 }
91 91
92 /// <summary>
93 /// Make sure our object does not timeout when in AppDomain. (Called by ILease base class)
94 /// </summary>
95 /// <returns></returns>
96 public override Object InitializeLifetimeService()
97 {
98 //m_log.Debug("Executor: InitializeLifetimeService()");
99 // return null;
100 ILease lease = (ILease)base.InitializeLifetimeService();
101
102 if (lease.CurrentState == LeaseState.Initial)
103 {
104 lease.InitialLeaseTime = TimeSpan.Zero; // TimeSpan.FromMinutes(1);
105 // lease.SponsorshipTimeout = TimeSpan.FromMinutes(2);
106 // lease.RenewOnCallTime = TimeSpan.FromSeconds(2);
107 }
108 return lease;
109 }
110
111
112 public scriptEvents GetStateEventFlags(string state) 92 public scriptEvents GetStateEventFlags(string state)
113 { 93 {
114 //m_log.Debug("Get event flags for " + state); 94 //m_log.Debug("Get event flags for " + state);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
index 9068634..753ca55 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
@@ -32,7 +32,7 @@ using LSLInteger = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
32 32
33namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase 33namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
34{ 34{
35 public partial class ScriptBaseClass : MarshalByRefObject 35 public partial class ScriptBaseClass
36 { 36 {
37 // LSL CONSTANTS 37 // LSL CONSTANTS
38 public static readonly LSLInteger TRUE = new LSLInteger(1); 38 public static readonly LSLInteger TRUE = new LSLInteger(1);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs
index 964fe4c..d119a77 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs
@@ -26,6 +26,7 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Runtime.Remoting;
29using System.Runtime.Remoting.Lifetime; 30using System.Runtime.Remoting.Lifetime;
30using System.Security.Permissions; 31using System.Security.Permissions;
31using System.Threading; 32using System.Threading;
@@ -34,26 +35,23 @@ using System.Collections;
34using System.Collections.Generic; 35using System.Collections.Generic;
35using OpenSim.Region.ScriptEngine.Interfaces; 36using OpenSim.Region.ScriptEngine.Interfaces;
36using OpenSim.Region.ScriptEngine.Shared; 37using OpenSim.Region.ScriptEngine.Shared;
38using OpenSim.Region.ScriptEngine.Shared.Api.Runtime;
37 39
38namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase 40namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
39{ 41{
40 public partial class ScriptBaseClass : MarshalByRefObject, IScript 42 public partial class ScriptBaseClass : MarshalByRefObject, IScript
41 { 43 {
42 private Dictionary<string, MethodInfo> inits = new Dictionary<string, MethodInfo>(); 44 private Dictionary<string, MethodInfo> inits = new Dictionary<string, MethodInfo>();
45 private ScriptSponsor m_sponser;
43 46
44 // Object expires if we don't keep it alive
45 // sponsor will be added on object load
46 [SecurityPermissionAttribute(SecurityAction.Demand,
47 Flags = SecurityPermissionFlag.Infrastructure)]
48 public override Object InitializeLifetimeService() 47 public override Object InitializeLifetimeService()
49 { 48 {
50 ILease lease = (ILease)base.InitializeLifetimeService(); 49 ILease lease = (ILease)base.InitializeLifetimeService();
51 if (lease.CurrentState == LeaseState.Initial) 50 if (lease.CurrentState == LeaseState.Initial)
52 { 51 {
53 lease.InitialLeaseTime = TimeSpan.Zero; 52 lease.InitialLeaseTime = TimeSpan.FromMinutes(1.0);
54// lease.InitialLeaseTime = TimeSpan.FromMinutes(1); 53 lease.RenewOnCallTime = TimeSpan.FromSeconds(10.0);
55// lease.SponsorshipTimeout = TimeSpan.FromMinutes(2); 54 lease.SponsorshipTimeout = TimeSpan.FromMinutes(1.0);
56// lease.RenewOnCallTime = TimeSpan.FromSeconds(2);
57 } 55 }
58 return lease; 56 return lease;
59 } 57 }
@@ -66,7 +64,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
66 } 64 }
67#endif 65#endif
68 66
69
70 public ScriptBaseClass() 67 public ScriptBaseClass()
71 { 68 {
72 m_Executor = new Executor(this); 69 m_Executor = new Executor(this);
@@ -81,6 +78,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
81 inits[type] = mi; 78 inits[type] = mi;
82 } 79 }
83 } 80 }
81
82 m_sponser = new ScriptSponsor();
84 } 83 }
85 84
86 private Executor m_Executor = null; 85 private Executor m_Executor = null;
@@ -112,6 +111,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
112 if (!inits.ContainsKey(api)) 111 if (!inits.ContainsKey(api))
113 return; 112 return;
114 113
114 ILease lease = (ILease)RemotingServices.GetLifetimeService(data as MarshalByRefObject);
115 lease.Register(m_sponser);
116
115 MethodInfo mi = inits[api]; 117 MethodInfo mi = inits[api];
116 118
117 Object[] args = new Object[1]; 119 Object[] args = new Object[1];
@@ -122,6 +124,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
122 m_InitialValues = GetVars(); 124 m_InitialValues = GetVars();
123 } 125 }
124 126
127 public void Close()
128 {
129 m_sponser.Close();
130 }
131
125 public Dictionary<string, object> GetVars() 132 public Dictionary<string, object> GetVars()
126 { 133 {
127 Dictionary<string, object> vars = new Dictionary<string, object>(); 134 Dictionary<string, object> vars = new Dictionary<string, object>();
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptSponsor.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptSponsor.cs
index a2da14e..977ac30 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptSponsor.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptSponsor.cs
@@ -32,15 +32,19 @@ using System.Text;
32 32
33namespace OpenSim.Region.ScriptEngine.Shared.Api.Runtime 33namespace OpenSim.Region.ScriptEngine.Shared.Api.Runtime
34{ 34{
35 [Serializable]
36 public class ScriptSponsor : MarshalByRefObject, ISponsor 35 public class ScriptSponsor : MarshalByRefObject, ISponsor
37 { 36 {
38 // In theory: I execute, therefore I am. 37 private bool m_closed = false;
39 // If GC collects this class then sponsorship will expire 38
40 public TimeSpan Renewal(ILease lease) 39 public TimeSpan Renewal(ILease lease)
41 { 40 {
42 return TimeSpan.FromMinutes(2); 41 if (!m_closed)
42 return lease.InitialLeaseTime;
43 return TimeSpan.FromTicks(0);
43 } 44 }
45
46 public void Close() { m_closed = true; }
47
44#if DEBUG 48#if DEBUG
45 // For tracing GC while debugging 49 // For tracing GC while debugging
46 public static bool GCDummy = false; 50 public static bool GCDummy = false;
diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
index 8168300..6d62249 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
@@ -96,7 +96,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
96 private string m_CurrentState = String.Empty; 96 private string m_CurrentState = String.Empty;
97 private UUID m_RegionID = UUID.Zero; 97 private UUID m_RegionID = UUID.Zero;
98 98
99 //private ISponsor m_ScriptSponsor; 99 private ScriptSponsor m_ScriptSponsor;
100 private bool m_destroyed = false;
100 private Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>> 101 private Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>>
101 m_LineMap; 102 m_LineMap;
102 103
@@ -261,12 +262,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
261 Path.GetFileNameWithoutExtension(assembly), 262 Path.GetFileNameWithoutExtension(assembly),
262 "SecondLife.Script"); 263 "SecondLife.Script");
263 264
264 // Add a sponsor to the script 265 m_ScriptSponsor = new ScriptSponsor();
265// ISponsor scriptSponsor = new ScriptSponsor(); 266 ILease lease = (ILease)RemotingServices.GetLifetimeService(m_Script as ScriptBaseClass);
266// ILease lease = (ILease)RemotingServices.GetLifetimeService(m_Script as MarshalByRefObject); 267 lease.Register(m_ScriptSponsor);
267// lease.Register(scriptSponsor);
268 //m_ScriptSponsor = scriptSponsor;
269
270 } 268 }
271 catch (Exception) 269 catch (Exception)
272 { 270 {
@@ -449,6 +447,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
449 { 447 {
450 ReleaseControls(); 448 ReleaseControls();
451 AsyncCommandManager.RemoveScript(m_Engine, m_LocalID, m_ItemID); 449 AsyncCommandManager.RemoveScript(m_Engine, m_LocalID, m_ItemID);
450
451 m_Script.Close();
452 m_ScriptSponsor.Close();
453 ILease lease = (ILease)RemotingServices.GetLifetimeService(m_Script as ScriptBaseClass);
454 lease.Unregister(m_ScriptSponsor);
455
456 m_destroyed = true;
452 } 457 }
453 458
454 public void RemoveState() 459 public void RemoveState()
@@ -884,6 +889,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
884 889
885 public void SaveState(string assembly) 890 public void SaveState(string assembly)
886 { 891 {
892
893
887 // If we're currently in an event, just tell it to save upon return 894 // If we're currently in an event, just tell it to save upon return
888 // 895 //
889 if (m_InEvent) 896 if (m_InEvent)
@@ -892,6 +899,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
892 return; 899 return;
893 } 900 }
894 901
902 // Data may not be available as the script has already been destroyed
903 if (m_destroyed == true)
904 return;
905
895 PluginData = AsyncCommandManager.GetSerializationData(m_Engine, m_ItemID); 906 PluginData = AsyncCommandManager.GetSerializationData(m_Engine, m_ItemID);
896 907
897 string xml = ScriptSerializer.Serialize(this); 908 string xml = ScriptSerializer.Serialize(this);
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
index c7673c7..ff75e2f 100644
--- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
+++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
@@ -272,6 +272,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine
272 instance.ClearQueue(); 272 instance.ClearQueue();
273 instance.Stop(0); 273 instance.Stop(0);
274 274
275 // Release events, timer, etc
276 //
277 instance.DestroyScriptInstance();
278
275 // Unload scripts and app domains 279 // Unload scripts and app domains
276 // Must be done explicitly because they have infinite 280 // Must be done explicitly because they have infinite
277 // lifetime 281 // lifetime
@@ -282,10 +286,6 @@ namespace OpenSim.Region.ScriptEngine.XEngine
282 m_DomainScripts.Remove(instance.AppDomain); 286 m_DomainScripts.Remove(instance.AppDomain);
283 UnloadAppDomain(instance.AppDomain); 287 UnloadAppDomain(instance.AppDomain);
284 } 288 }
285
286 // Release events, timer, etc
287 //
288 instance.DestroyScriptInstance();
289 } 289 }
290 m_Scripts.Clear(); 290 m_Scripts.Clear();
291 m_PrimObjects.Clear(); 291 m_PrimObjects.Clear();
@@ -802,6 +802,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine
802 } 802 }
803 } 803 }
804 804
805 instance.RemoveState();
806 instance.DestroyScriptInstance();
807
805 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); 808 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID);
806 if (m_DomainScripts[instance.AppDomain].Count == 0) 809 if (m_DomainScripts[instance.AppDomain].Count == 0)
807 { 810 {
@@ -809,9 +812,6 @@ namespace OpenSim.Region.ScriptEngine.XEngine
809 UnloadAppDomain(instance.AppDomain); 812 UnloadAppDomain(instance.AppDomain);
810 } 813 }
811 814
812 instance.RemoveState();
813 instance.DestroyScriptInstance();
814
815 instance = null; 815 instance = null;
816 816
817 ObjectRemoved handlerObjectRemoved = OnObjectRemoved; 817 ObjectRemoved handlerObjectRemoved = OnObjectRemoved;