2

running ANTS memory profiler I see that I have a lot of unused memory allocated to .net.

How do I determine what is causing this?

I have put a screenshot of the summary report generated by ANTS here: ANTS Summary report

Thanks Thomas

ThomasD
  • 2,302
  • 5
  • 32
  • 50
  • Try GC.Collect(), reprofile and post output – Eugen Rieck Jan 26 '12 at 22:17
  • You need to continue analyzing the trace and find out which objects are being allocated on the LOH that may be contributing tho fragmentation. – Ed S. Jan 26 '12 at 22:17
  • 1
    @EugenRieck: The problem is LOH fragmentation and compaction is not deterministic. The GC will not perform compaction, so manually calling `GC.Collect()` will not help. – Ed S. Jan 26 '12 at 22:18
  • I meant: Try GC.Collect() **along the way before**, reprofile and post output - see http://stackoverflow.com/questions/8972758/is-it-smart-to-use-gc-collect-on-application-that-runs-24h-per-day for where I am looking – Eugen Rieck Jan 26 '12 at 22:20
  • 1
    @EugenRieck: Still not seeing how that's relevant. LOH fragmentation occurs when many objects are allocated on the LOH (i.e., they are > 85000 bytes), deallocated over time, but no compaction occurs, thus there are a bunch of little "holes" in the heap where objects that are too large cannot be allocated. So you end up allocating a lot more memory than you need due to the gaps. – Ed S. Jan 26 '12 at 22:26
  • Might be relevant, might be not: In many cases large objects are allocated in a method, go out of scope at the end of the method, in the next method call another large object is allocated on top of this before the GC kicks in and does NOT go out of scope. When GC finally runs, the short-lived objects are collected and make swiss chese out of your heap. In this case, a call to `GC.Collect()` at the end of the first method cal (after clearing your references) helps. This is what I meant with "having more info than the GC" in the other Answer – Eugen Rieck Jan 26 '12 at 22:31
  • @EugenRieck: If they're allocated on the LOH is makes absolutely no difference since the GC will not perform compaction and that is the problem here. GC kicking in or not is irrelevant. – Ed S. Jan 26 '12 at 22:32
  • I am not talking of compaction. I am talking of collecting the **last** object(s) on the LOH, therefore making compaction at a later point in time unnecessary. Ofcourse collection of the **last** object(s) can only be done immediately after they are no longer used, before new objects are allocated on the LOH - that's why I recommended calling `GC.Collect()` at the end of a method, that creates object(s) on the LOH, that are no longer used. If they are collected right then, compaction will not be necessary. – Eugen Rieck Jan 26 '12 at 22:36
  • @EugenRieck: Yeah I was thinking on a bit more while taking a smoke and I see what you're getting at. It can't hurt to try, it really just depends on what the code is doing and if the GC decides to clean those up. – Ed S. Jan 26 '12 at 22:39
  • @EdS. please let me know your results: This is an active field of investigation to me, as some of my apps bounce against 2G limits on 32bit quite often. Taking a smoke myself now. – Eugen Rieck Jan 26 '12 at 22:42
  • @EugenRieck: You know I have fixed quite a few memory issues in .NET apps before. If you would like some help outside of the comments here i'd be happy to help. Feel free to send me info at the email address on my profile. In the past I have used Redgate's ANTS .NET mem. profiler with great success. It's free for two weeks if you haven't tried it (and no, I don't work for or with them :D – Ed S. Jan 26 '12 at 22:54
  • I just setup a loadtest with http://www.loadtestingtool.com/ hitting my app with 100 user sessions on my local box. I then ran a memory profiler. You can see the results here: http://screencast.com/t/qN0ZcIO6u0 . Should I run the GC.Collect(), rerun the loadtest, reprofile and screenshot the report? Or would there be a better way. Btw, the first screenshot in my question is from my production system. It is just a bit easier to profile on my local box for now – ThomasD Jan 26 '12 at 22:59
  • @EugenRieck this the snapshot after hitting it with 100 session and garbace collecting with GC.Collect() http://screencast.com/t/hYtvytpmwCIH – ThomasD Jan 26 '12 at 23:17
  • On your first report you had 3.5 GB allocated for 238MB used (6.6% used), in the first of the newer reports you have 133.8/236.7 MB used (56.5%), in the newest report you have 143.5/265.5 MB used (54.0%) - so the unused overhead is different by a power of 10 between production box and local box ... – Eugen Rieck Jan 26 '12 at 23:46
  • I only have one question about this question: **Who the heck cares?** What's causing this is automatic memory management. Automatic means you don't (and shouldn't) fool with it. – Cody Gray Jan 27 '12 at 04:03
  • @CodyGray I am trying to locate a memory leak which causes my app to crash. And what puzzles me is that the unused memory allocated to .net is so large. – ThomasD Jan 27 '12 at 09:36
  • @EugenRieck I guess the difference between the prod-report and local-reports is due to my stress test on the local box not being as intensive as on the prod. I am trying to identify a memory leak. Do you think I am down the right path and if so, that the unused memory on the prod-machine is the problem or not? Your help is really appreciated! Thanks – ThomasD Jan 27 '12 at 09:58
  • @ThomasD I really can't say from the data I have seen so far. I'd suggest you run a bigger load test and repost, I'll try to help. – Eugen Rieck Jan 27 '12 at 10:02
  • @EugenRieck. Thanks alot! I will run a bigger test on my local box, and repost. Would you say that the 3.5 GB allocated for 238MB used (6.6% used) is an unusual ratio? – ThomasD Jan 27 '12 at 10:13
  • @ThomasD absolutely: This smells like swiss cheese on the heap – Eugen Rieck Jan 27 '12 at 10:29
  • @EugenRieck This is the first time I have had to handle memory leaks, so my knowledge is very limited. Is it mainly the objects on the Large Object Heap, that would cause this? And if so, is there any way I can look into the Large Object Heap over time to identify the culprit(s). Looking at the large object heap with Ants just shows me three entries: http://screencast.com/t/urDtJpRKUVo. The Place-array is quite large with children:http://screencast.com/t/BDIWdnSvbi5 – ThomasD Jan 27 '12 at 11:21
  • @EugenRieck I think I figured out what was causing the memory leak (partially anyway). As you pointed out, the relative memory consumption on the local box is a lot less than on the production box.It turned out that my local box was set to allow 32-bit applications whereas the prod. server was not. I then set the prod-server to allow 32-bit, and now it works. The site is on the open source CMS Umbraco, and I need to figure out how to run 64 bit. But for now I will manage. Thank you for your help! – ThomasD Jan 28 '12 at 06:10
  • Seems like in the future post .NET 4.5 compacting LOH programatically will be an option. Quote from a CLR PM: "Providing developers a feature to trigger LOH compaction is in the list of things we wish to do in future. As you would understand, this list has other feature requests as well, and we keep evaluating them continuously to ensure that we provide the best value to our developers with the resources available on our end." http://blogs.msdn.com/b/dotnet/archive/2011/10/04/large-object-heap-improvements-in-net-4-5.aspx – Patrick from NDepend team Mar 06 '13 at 13:34

0 Answers0