From de2a49dddfd9854106ec2f75407403577f60cbab Mon Sep 17 00:00:00 2001 From: John Hurliman Date: Tue, 20 Apr 2010 21:58:23 +0000 Subject: [PATCH] First round of memory improvements! * Disable TRACK_UTILIZATION by default * Ignore Primitive.ScratchPad and always set it to Utils.EmptyBytes. This field is deprecated on the SL grid and there are better ways to extend the protocol for non-SL grids * More graceful handling of corrupted wearables * Free up memory after baking git-svn-id: http://libopenmetaverse.googlecode.com/svn/libopenmetaverse/trunk@3297 52acb1d6-8a22-11de-b505-999d5b087335 --- OpenMetaverse/AppearanceManager.cs | 13 +- .../Assets/AssetTypes/AssetWearable.cs | 236 +++++++++--------- OpenMetaverse/ObjectManager.cs | 20 +- OpenMetaverse/Primitives/Primitive.cs | 2 +- OpenMetaverse/Settings.cs | 2 +- 5 files changed, 148 insertions(+), 125 deletions(-) diff --git a/OpenMetaverse/AppearanceManager.cs b/OpenMetaverse/AppearanceManager.cs index 4979652c..c87af84c 100644 --- a/OpenMetaverse/AppearanceManager.cs +++ b/OpenMetaverse/AppearanceManager.cs @@ -1465,7 +1465,7 @@ namespace OpenMetaverse private bool CreateBakes() { bool success = true; - List pendingBakes = new List(0); + List pendingBakes = new List(); // Check each bake layer in the Textures array for missing bakes for (int bakedIndex = 0; bakedIndex < BAKED_TEXTURE_COUNT; bakedIndex++) @@ -1495,6 +1495,17 @@ namespace OpenMetaverse ); } + // Free up all the textures we're holding on to + for (int i = 0; i < Textures.Length; i++) + { + Textures[i].Texture = null; + Textures[i].TextureID = UUID.Zero; + } + + // We just allocated and freed a ridiculous amount of memory while + // baking. Signal to the GC to clean up + GC.Collect(); + return success; } diff --git a/OpenMetaverse/Assets/AssetTypes/AssetWearable.cs b/OpenMetaverse/Assets/AssetTypes/AssetWearable.cs index 97b007ea..24208f43 100644 --- a/OpenMetaverse/Assets/AssetTypes/AssetWearable.cs +++ b/OpenMetaverse/Assets/AssetTypes/AssetWearable.cs @@ -86,130 +86,140 @@ namespace OpenMetaverse.Assets { int version = -1; Permissions = new Permissions(); - string data = Utils.BytesToString(AssetData); - data = data.Replace("\r", String.Empty); - string[] lines = data.Split('\n'); - for (int stri = 0; stri < lines.Length; stri++) + try { - if (stri == 0) - { - string versionstring = lines[stri]; - version = Int32.Parse(versionstring.Split(' ')[2]); - if (version != 22 && version != 18) - return false; - } - else if (stri == 1) - { - Name = lines[stri]; - } - else if (stri == 2) - { - Description = lines[stri]; - } - else - { - string line = lines[stri].Trim(); - string[] fields = line.Split('\t'); + string data = Utils.BytesToString(AssetData); - if (fields.Length == 1) + data = data.Replace("\r", String.Empty); + string[] lines = data.Split('\n'); + for (int stri = 0; stri < lines.Length; stri++) + { + if (stri == 0) { - fields = line.Split(' '); - if (fields[0] == "parameters") - { - int count = Int32.Parse(fields[1]) + stri; - for (; stri < count; ) - { - stri++; - line = lines[stri].Trim(); - fields = line.Split(' '); - - int id = Int32.Parse(fields[0]); - if (fields[1] == ",") - fields[1] = "0"; - else - fields[1] = fields[1].Replace(',', '.'); - - float weight = float.Parse(fields[1], System.Globalization.NumberStyles.Float, - Utils.EnUsCulture.NumberFormat); - - Params[id] = weight; - } - } - else if (fields[0] == "textures") - { - int count = Int32.Parse(fields[1]) + stri; - for (; stri < count; ) - { - stri++; - line = lines[stri].Trim(); - fields = line.Split(' '); - - AvatarTextureIndex id = (AvatarTextureIndex)Int32.Parse(fields[0]); - UUID texture = new UUID(fields[1]); - - Textures[id] = texture; - } - } - else if (fields[0] == "type") - { - WearableType = (WearableType)Int32.Parse(fields[1]); - } - + string versionstring = lines[stri]; + version = Int32.Parse(versionstring.Split(' ')[2]); + if (version != 22 && version != 18) + return false; } - else if (fields.Length == 2) + else if (stri == 1) { - switch (fields[0]) + Name = lines[stri]; + } + else if (stri == 2) + { + Description = lines[stri]; + } + else + { + string line = lines[stri].Trim(); + string[] fields = line.Split('\t'); + + if (fields.Length == 1) { - case "creator_mask": - // Deprecated, apply this as the base mask - Permissions.BaseMask = (PermissionMask)UInt32.Parse(fields[1], System.Globalization.NumberStyles.HexNumber); - break; - case "base_mask": - Permissions.BaseMask = (PermissionMask)UInt32.Parse(fields[1], System.Globalization.NumberStyles.HexNumber); - break; - case "owner_mask": - Permissions.OwnerMask = (PermissionMask)UInt32.Parse(fields[1], System.Globalization.NumberStyles.HexNumber); - break; - case "group_mask": - Permissions.GroupMask = (PermissionMask)UInt32.Parse(fields[1], System.Globalization.NumberStyles.HexNumber); - break; - case "everyone_mask": - Permissions.EveryoneMask = (PermissionMask)UInt32.Parse(fields[1], System.Globalization.NumberStyles.HexNumber); - break; - case "next_owner_mask": - Permissions.NextOwnerMask = (PermissionMask)UInt32.Parse(fields[1], System.Globalization.NumberStyles.HexNumber); - break; - case "creator_id": - Creator = new UUID(fields[1]); - break; - case "owner_id": - Owner = new UUID(fields[1]); - break; - case "last_owner_id": - LastOwner = new UUID(fields[1]); - break; - case "group_id": - Group = new UUID(fields[1]); - break; - case "group_owned": - GroupOwned = (Int32.Parse(fields[1]) != 0); - break; - case "sale_type": - ForSale = Utils.StringToSaleType(fields[1]); - break; - case "sale_price": - SalePrice = Int32.Parse(fields[1]); - break; - case "sale_info": - // Container for sale_type and sale_price, ignore - break; - default: - return false; + fields = line.Split(' '); + if (fields[0] == "parameters") + { + int count = Int32.Parse(fields[1]) + stri; + for (; stri < count; ) + { + stri++; + line = lines[stri].Trim(); + fields = line.Split(' '); + + int id = Int32.Parse(fields[0]); + if (fields[1] == ",") + fields[1] = "0"; + else + fields[1] = fields[1].Replace(',', '.'); + + float weight = float.Parse(fields[1], System.Globalization.NumberStyles.Float, + Utils.EnUsCulture.NumberFormat); + + Params[id] = weight; + } + } + else if (fields[0] == "textures") + { + int count = Int32.Parse(fields[1]) + stri; + for (; stri < count; ) + { + stri++; + line = lines[stri].Trim(); + fields = line.Split(' '); + + AvatarTextureIndex id = (AvatarTextureIndex)Int32.Parse(fields[0]); + UUID texture = new UUID(fields[1]); + + Textures[id] = texture; + } + } + else if (fields[0] == "type") + { + WearableType = (WearableType)Int32.Parse(fields[1]); + } + + } + else if (fields.Length == 2) + { + switch (fields[0]) + { + case "creator_mask": + // Deprecated, apply this as the base mask + Permissions.BaseMask = (PermissionMask)UInt32.Parse(fields[1], System.Globalization.NumberStyles.HexNumber); + break; + case "base_mask": + Permissions.BaseMask = (PermissionMask)UInt32.Parse(fields[1], System.Globalization.NumberStyles.HexNumber); + break; + case "owner_mask": + Permissions.OwnerMask = (PermissionMask)UInt32.Parse(fields[1], System.Globalization.NumberStyles.HexNumber); + break; + case "group_mask": + Permissions.GroupMask = (PermissionMask)UInt32.Parse(fields[1], System.Globalization.NumberStyles.HexNumber); + break; + case "everyone_mask": + Permissions.EveryoneMask = (PermissionMask)UInt32.Parse(fields[1], System.Globalization.NumberStyles.HexNumber); + break; + case "next_owner_mask": + Permissions.NextOwnerMask = (PermissionMask)UInt32.Parse(fields[1], System.Globalization.NumberStyles.HexNumber); + break; + case "creator_id": + Creator = new UUID(fields[1]); + break; + case "owner_id": + Owner = new UUID(fields[1]); + break; + case "last_owner_id": + LastOwner = new UUID(fields[1]); + break; + case "group_id": + Group = new UUID(fields[1]); + break; + case "group_owned": + GroupOwned = (Int32.Parse(fields[1]) != 0); + break; + case "sale_type": + ForSale = Utils.StringToSaleType(fields[1]); + break; + case "sale_price": + SalePrice = Int32.Parse(fields[1]); + break; + case "sale_info": + // Container for sale_type and sale_price, ignore + break; + default: + return false; + } } } } } + catch (Exception ex) + { + Logger.Log("Failed decoding wearable asset " + this.AssetID + ": " + ex.Message, + Helpers.LogLevel.Warning); + return false; + } return true; } diff --git a/OpenMetaverse/ObjectManager.cs b/OpenMetaverse/ObjectManager.cs index 546132c4..1ac2c682 100644 --- a/OpenMetaverse/ObjectManager.cs +++ b/OpenMetaverse/ObjectManager.cs @@ -1970,14 +1970,15 @@ namespace OpenMetaverse prim.TreeSpecies = (Tree)block.Data[0]; else Logger.Log("Got a foliage update with an invalid TreeSpecies field", Helpers.LogLevel.Warning); - prim.ScratchPad = Utils.EmptyBytes; - break; - default: - prim.ScratchPad = new byte[block.Data.Length]; - if (block.Data.Length > 0) - Buffer.BlockCopy(block.Data, 0, prim.ScratchPad, 0, prim.ScratchPad.Length); + // prim.ScratchPad = Utils.EmptyBytes; + // break; + //default: + // prim.ScratchPad = new byte[block.Data.Length]; + // if (block.Data.Length > 0) + // Buffer.BlockCopy(block.Data, 0, prim.ScratchPad, 0, prim.ScratchPad.Length); break; } + prim.ScratchPad = Utils.EmptyBytes; // Packed parameters prim.CollisionPlane = objectupdate.CollisionPlane; @@ -2336,7 +2337,7 @@ namespace OpenMetaverse if ((flags & CompressedFlags.Tree) != 0) { prim.TreeSpecies = (Tree)block.Data[i++]; - prim.ScratchPad = Utils.EmptyBytes; + //prim.ScratchPad = Utils.EmptyBytes; } // Scratch pad else if ((flags & CompressedFlags.ScratchPad) != 0) @@ -2344,10 +2345,11 @@ namespace OpenMetaverse prim.TreeSpecies = (Tree)0; int size = block.Data[i++]; - prim.ScratchPad = new byte[size]; - Buffer.BlockCopy(block.Data, i, prim.ScratchPad, 0, size); + //prim.ScratchPad = new byte[size]; + //Buffer.BlockCopy(block.Data, i, prim.ScratchPad, 0, size); i += size; } + prim.ScratchPad = Utils.EmptyBytes; // Floating text if ((flags & CompressedFlags.HasText) != 0) diff --git a/OpenMetaverse/Primitives/Primitive.cs b/OpenMetaverse/Primitives/Primitive.cs index 9bd830d3..91ca5074 100644 --- a/OpenMetaverse/Primitives/Primitive.cs +++ b/OpenMetaverse/Primitives/Primitive.cs @@ -769,7 +769,7 @@ namespace OpenMetaverse Buffer.BlockCopy(prim.ScratchPad, 0, ScratchPad, 0, ScratchPad.Length); } else - ScratchPad = null; + ScratchPad = Utils.EmptyBytes; Position = prim.Position; Scale = prim.Scale; Rotation = prim.Rotation; diff --git a/OpenMetaverse/Settings.cs b/OpenMetaverse/Settings.cs index 48b75d6d..d58c3ae7 100644 --- a/OpenMetaverse/Settings.cs +++ b/OpenMetaverse/Settings.cs @@ -234,7 +234,7 @@ namespace OpenMetaverse /// If true, utilization statistics will be tracked. There is a minor penalty /// in CPU time for enabling this option. /// - public bool TRACK_UTILIZATION = true; + public bool TRACK_UTILIZATION = false; #endregion #region Parcel Tracking