private const float mbyte = 1048576; Process proc = Process.GetCurrentProcess(); string privMemSize = (proc.PrivateMemorySize64 / mbyte).ToString("0.0000");
string gcTotalMem = (GC.GetTotalMemory(false) / mbyte).ToString("0.0000");
private static string GetObjectSize(object TestObject) { try { BinaryFormatter bf = new BinaryFormatter(); MemoryStream ms = new MemoryStream(); byte[] Array; bf.Serialize(ms, TestObject); Array = ms.ToArray(); return ((float)Array.Length / mbyte).ToString("0.00000"); } catch (Exception ex) { log.Error("========================================================================\n" +ex.Message + "\n" + ex.StackTrace + "\n" + "========================================================================\n"); return "error"; } }
ArcMap is a 32 bit process. By default it can access 2 ** 32 / 2 bytes of memory. If you run it on a 64 bit machine with a 64 bit OS then it can access 2 ** 32 bytes of memory. In essence, you get 4 GB instead of 2 GB.
INFO 2013-03-19 08:18:57,083 â?? Called FindFlowElements method 3213 time(s) Process name: ArcMap -> memory usage 1588,7460 MB || GC TotalMemory -> 264,3199 MB INFO 2013-03-19 08:19:00,717 â?? Called FindFlowElements method 3214 time(s) Process name: ArcMap -> memory usage 1492,2500 MB || GC TotalMemory -> 176,0005 MB INFO 2013-03-19 08:19:04,430 â?? Called FindFlowElements method 3215 time(s) Process name: ArcMap -> memory usage 1611,6560 MB || GC TotalMemory -> 297,3569 MB
INFO 2013-03-19 10:18:29,839 â?? Called FindFlowElements method 4823 time(s) Process name: ArcMap -> memory usage 2010,1130 MB || GC TotalMemory -> 221,0689 MB INFO 2013-03-19 10:18:40,649 â?? Called FindFlowElements method 4824 time(s) Process name: ArcMap -> memory usage -1884,5430 MB || GC TotalMemory -> 423,0786 MB INFO 2013-03-19 10:18:44,892 â?? Called FindFlowElements method 4825 time(s) Process name: ArcMap -> memory usage -1682,0350 MB || GC TotalMemory -> 620,8250 MB INFO 2013-03-19 10:18:49,229 â?? Called FindFlowElements method 4826 time(s) Process name: ArcMap -> memory usage 1976,2620 MB || GC TotalMemory -> 183,4406 MB
Thanks for replying, my mistake that i didn't post the machine specification. We are testing this utility on two PC:
1. Windows Server 2008 R2 Foundation 64 bit
Intel Xeon X3430 @ 2.40 GHz
8 GB RAM
2.Windows 7 Proffessional 64 bit
Intel i7-2600K @ 3.40GHz
8 GB RAM
On both PC the version of ArcGIS is 10.0.
Yep I've read that arcmap is native 32-bit process and it can use 4GB of ram BUT still I dont think in that process I need so much memory..
In case of releasing the COM object, we are doing it every time when we use a COM object with ReleaseComObject method. Since we wanted to fasten the application and shorten the time needed to analyze so much data at the beggining we are creating dictionaries from feature attributes table(of course not all attributes, just the one we need). The code sample you are asking for I'm attaching in txt file.
I did today another hard test with this utility and something really weird is happening with ArcMap, I will show you few Inof's from log file(noone else was using any of the PC's in our office):
INFO 2013-03-19 08:18:57,083 â?? Called FindFlowElements method 3213 time(s) Process name: ArcMap -> memory usage 1588,7460 MB || GC TotalMemory -> 264,3199 MB INFO 2013-03-19 08:19:00,717 â?? Called FindFlowElements method 3214 time(s) Process name: ArcMap -> memory usage 1492,2500 MB || GC TotalMemory -> 176,0005 MB INFO 2013-03-19 08:19:04,430 â?? Called FindFlowElements method 3215 time(s) Process name: ArcMap -> memory usage 1611,6560 MB || GC TotalMemory -> 297,3569 MB
Only 7seconds and so much difference in memory usage...that's weird isn't it?
Later get's better;) ->
INFO 2013-03-19 10:18:29,839 â?? Called FindFlowElements method 4823 time(s) Process name: ArcMap -> memory usage 2010,1130 MB || GC TotalMemory -> 221,0689 MB INFO 2013-03-19 10:18:40,649 â?? Called FindFlowElements method 4824 time(s) Process name: ArcMap -> memory usage -1884,5430 MB || GC TotalMemory -> 423,0786 MB INFO 2013-03-19 10:18:44,892 â?? Called FindFlowElements method 4825 time(s) Process name: ArcMap -> memory usage -1682,0350 MB || GC TotalMemory -> 620,8250 MB INFO 2013-03-19 10:18:49,229 â?? Called FindFlowElements method 4826 time(s) Process name: ArcMap -> memory usage 1976,2620 MB || GC TotalMemory -> 183,4406 MB
Funny(or maybe it's normal??)? At the same time notice the increase of Garbage Collector managed memory and 5 sec later it's down over 400MB. I'm not the expert in memory managing but it looks weird.
If you got any idea about this please share you knowledge I'm very curious about this.
private static void GetSelectedFeatures(IFeatureLayer featLayer, string layerName, Dictionary<string, string> dc) { ICursor cursor = null; IRow row = null; try { cursor = Utilities.GetCursor(featLayer); row = cursor.NextRow(); while (row != null) { string nadrzedny = Utilities.GetStringValueFromField(row, FIELD_NAME_NADRZEDNY); string uniqueNR = Utilities.GetStringValueFromField(row, FIELD_NAME_UNIKALNY); if (!dc.ContainsKey(nadrzedny)) dc.Add(nadrzedny, uniqueNR); // release each instance of row Marshal.ReleaseComObject(row); // set it to null in case the next line throws an exception // don't want to release it a second time in the finally-block row = null; row = cursor.NextRow(); } } finally { // row should be null unless an exception occurred, in which case // the last allocated instance of row should still be released if( row != null ) Marshal.ReleaseComObject(row); Marshal.ReleaseComObject(cursor); } GetFinalListOfFeatures(layerName); }
I'll address the methods one at a time as needed. I really don't understand why you are interested in the memory usage totals. You should be concerned with what objects are using the most memory. Anyway, here is the first method:private static void GetSelectedFeatures(IFeatureLayer featLayer, string layerName, Dictionary<string, string> dc) { ICursor cursor = null; IRow row = null; try { cursor = Utilities.GetCursor(featLayer); row = cursor.NextRow(); while (row != null) { string nadrzedny = Utilities.GetStringValueFromField(row, FIELD_NAME_NADRZEDNY); string uniqueNR = Utilities.GetStringValueFromField(row, FIELD_NAME_UNIKALNY); if (!dc.ContainsKey(nadrzedny)) dc.Add(nadrzedny, uniqueNR); // release each instance of row Marshal.ReleaseComObject(row); // set it to null in case the next line throws an exception // don't want to release it a second time in the finally-block row = null; row = cursor.NextRow(); } } finally { // row should be null unless an exception occurred, in which case // the last allocated instance of row should still be released if( row != null ) Marshal.ReleaseComObject(row); Marshal.ReleaseComObject(cursor); } GetFinalListOfFeatures(layerName); }
Code examples would help us to identify the problem. Also, you can use tools like CLR Profiler, UMDH, and LeakDiag to quickly identify which objects are consuming the most memory. Once you know which ones are consuming the most memory, you can focus your attention on getting them released properly. Or, you can do what I do, and make sure everything is released immediately after it is no longer needed--this approach is error prone, so be very careful if you try it.
cache*C:\dev\symbols;SRV*C:\dev\symbols*http://msdl.microsoft.com/download/symbols;SRV*C:\dev\symbols*http://downloads2.esri.com/Support/symbols/