|
dev
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
Calculate memory consumed.Hello all,
In my application I have a datacache class which stores xml objects which are frequently used. Caching objects can improve performance but they come at the cost of memory and in my case since the number of xml objects can be huge I wanted to put an upper limit to the memory allocated to the Cache class. Is there a way in dotnet that I can find out the total memory consumed by a class. similar to Environment.WorkingSet which gives the memory consumed for the entire application. Thanks in advance.. Praveen. "Praveen" <praveen@newsgroup.nospam> wrote: For a single type? Iterate through each field and sum up the values: use> In my application I have a datacache class which stores xml objects which > are frequently used. Caching objects can improve performance but they come > at the cost of memory and in my case since the number of xml objects can be > huge I wanted to put an upper limit to the memory allocated to the Cache > class. > > Is there a way in dotnet that I can find out the total memory consumed by a > class. similar to Environment.WorkingSet which gives the memory consumed for > the entire application. Marshal.SizeOf for value types and IntPtr.Size for reference types. For instances, you'll have to work a lot harder, especially if you want the total size of the graph being referred to. You'll need to guard against recursion of references and avoid double-counting value types, which will be boxed when you try to use reflection to examine their fields. You'll need permissions to look inside the private members too. You could also consider wrapping your cache objects in a WeakReference so the GC can collect occasionally. Truism: the trickiest part about caching is getting a good expiration policy right, otherwise it's just a memory leak. -- Barry Thanks Barry for your informative input.
Hi Praveen, Thank you for your post. As Barry pointed out, a good expiration policy of is key to your caching system. To get memory size of a single type, we can use Type.TypeHandle to get the basic instance size of this type. You can use following code to test: ===== using System; class SimpleClass { private byte b1 = 1; // 1 byte private byte b2 = 2; // 1 byte private byte b3 = 3; // 1 byte private byte b4 = 4; // 1 byte private char c1 = 'A'; // 2 bytes private char c2 = 'B'; // 2 bytes private short s1 = 11; // 2 bytes private short s2 = 12; // 2 bytes private int i1 = 21; // 4 bytes private long l1 = 31; // 8 bytes private string str = "MyString"; // 4 bytes (only OBJECTREF) //Total instance variable size = 28 bytes static void Main() { SimpleClass simpleObj = new SimpleClass(); int basicInstanceSize = GetBasicInstanceSize(simpleObj.GetType()); Console.Write(basicInstanceSize); } /// <summary> /// Gets the size of instances of the given type. It is the sum of: /// - a fixed object overhead (8 bytes) /// - the sizes of all the instance fields (note: may include padding) /// For more information see: /// - http://msdn.microsoft.com/msdnmag/issues/05/05/JITCompiler/default.aspx /// - http://msdn.microsoft.com/msdnmag/issues/05/05/JITCompiler/default.aspx?fig= true#fig9 /// </summary> /// <param name="type">A type.</param> /// <returns>Size in bytes of instances of the given type.</returns> private static int GetBasicInstanceSize(Type type) { // Read the first 8 bytes (=2 ints) of the MethodTable. The basic instance size is the second int. IntPtr methodTableIntPtr = IntPtr.Zero; try { methodTableIntPtr = type.TypeHandle.Value; int[] methodTableData = new int[2]; System.Runtime.InteropServices.Marshal.Copy(methodTableIntPtr, methodTableData, 0, 2); int basicInstanceSize = methodTableData[1]; return basicInstanceSize; } finally { if (methodTableIntPtr != IntPtr.Zero) System.Runtime.InteropServices.Marshal.Release(methodTableIntPtr); } } } ===== Hope this helps. Please feel free to post here if anything is unclear. Sincerely, Walter Wang (waw***@online.microsoft.com, remove 'online.') Microsoft Online Community Support ================================================== Get notification to my posts through email? Please refer to http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif ications. Note: The MSDN Managed Newsgroup support offering is for non-urgent issues where an initial response from the community or a Microsoft Support Engineer within 1 business day is acceptable. Please note that each follow up response may take approximately 2 business days as the support professional working with you may need further investigation to reach the most efficient resolution. The offering is not appropriate for situations that require urgent, real-time or phone-based interactions or complex project analysis and dump analysis issues. Issues of this nature are best handled working with a dedicated Microsoft Support Engineer by contacting Microsoft Customer Support Services (CSS) at http://msdn.microsoft.com/subscriptions/support/default.aspx. ================================================== This posting is provided "AS IS" with no warranties, and confers no rights. waw***@online.microsoft.com (Walter Wang [MSFT]) wrote:
> To get memory size of a single type, we can use Type.TypeHandle to get the This low-level hacking might not work in other implementations of the> basic instance size of this type. You can use following code to test: > // Read the first 8 bytes (=2 ints) of the MethodTable. The basic > instance size is the second int. CLI, and could change in future versions. There's nothing in the CLI that mandates the existence or layout of a method table, to my knowledge. I wouldn't recommend this method. The only mention of a method table I can find in the CLI is in reference to the contents of the PE file metadata. (I am aware of method tables from spelunking with WinDbg & SOS, and the SSCLI sources.) -- Barry Hi Barry,
Thank you. I should have pointed out that this is undocumented and may change in future version. Also this approach can only report basic instance size of a type, not necessary a runtime instance size. Another approach would be using .NET Profiler API to get object size. #Inspect and Optimize Your Program's Memory Usage with the .NET Profiler API http://msdn.microsoft.com/msdnmag/issues/03/01/netprofilerapi/ Regards, Walter Wang (waw***@online.microsoft.com, remove 'online.') Microsoft Online Community Support ================================================== When responding to posts, please "Reply to Group" via your newsreader so that others may learn and benefit from your issue. ================================================== This posting is provided "AS IS" with no warranties, and confers no rights. |
|||||||||||||||||||||||