0

I have a desktop app. Its purpose is to connect to 4 digital cameras and display onto a form using the VLC bindings. Its other purpose is to discern motion and upload to my server.

I throttle the FPS to 10 frames per second. It never goes beyond this FPS.

If i run it on my PC which is a Quad core 8gb RAM then all works OK.

If I run it on a friends PC which is Duo Core 4gb RAM it can run for days before a memory exception causes the app to bomb out.

The timing of when it crashes is unpredictable. I have error handlers everywhere (being paranoid :) ) but the only error ever reported is an Out of memory Exception which will occur randomly. I interpreted this as the cause f the exception is somewhere else.

I am using EMGU with C#.

I installed DotMemory - JetBrain and have taken random snapshots. Nothing ever seems untowward. No memory spikes or objects not being disposed.

This is screenshot of this:

enter image description here

Now, the 'green area' has obviously dominated. But what steps should I take now?

Thanks Anyone!

Additional:

enter image description here

This is where it starts. Yet, the code/functionality is just the same...

Andrew Simpson
  • 6,883
  • 11
  • 79
  • 179
  • 1
    Search for [tutorials](https://www.google.co.uk/?q=jetbrains+memory+profiler+tutorial). There are a few videos from JetBrains [here](https://www.jetbrains.com/profiler/documentation/documentation.jsp), I would start from the "Working with Profiling Results in dotTrace Performance". Things that worked for me is a *difference* - you take several snapshots every minute or so and then explore what has changed. It will be something like dictionary increased in size, or bytes in arrays grew a lot. From there you should be able to understand which exactly dictionary or array increased its size. – oleksii Nov 12 '14 at 08:55
  • Hi, thanks for your comment. I had obviously looked at the tutorial 1st :). The problem I have is that the results contradict themselves. A high level of Heap Gen2 would imply objects not being disposed. But as you may see from the snapshot(s) the object growth has not noticeably gone up :( +1 for anyone who tries to help me though :) – Andrew Simpson Nov 12 '14 at 08:58
  • 1
    Try monitoring at the app start. You should see MBs in memory. Gen2 doesn't indicate that the objects weren't disposed - they just survived GC and are supposedly used by your app. The picture shows result close to the crash, what you need to do is "rewind" back to the begining and observe which objects are promoted from Gen0 to Gen1 and then further to Gen2. It could be something like a loop going through too many bytes. Make sense? – oleksii Nov 12 '14 at 09:02
  • 1
    I need to know several things, and may be then will help you. Is your app 64 or 32bit? Is OS where you obtain OOM exception 64 or 32bit? On your screenshot I see that 1.5Gb of managed memory is occupied. Get snapshot at this memory loading level and ensure that all these objects are needed by app and it is not a memory leak. See this tutorial https://www.youtube.com/watch?v=0jiUb2hb9xs Is loading of Large Object Heap is always low (like on screenshot)? Check it after a day(s). Fragmentation of LOH can cause a OOM exception. https://www.jetbrains.com/dotmemory/webhelp/Heap_Fragmentation.html – Ed Pavlov Nov 12 '14 at 10:14
  • 2
    Assuming you're still looking for clues, this is worth reading: ["Out of memory" does not refer to physical memory](http://blogs.msdn.com/b/ericlippert/archive/2009/06/08/out-of-memory-does-not-refer-to-physical-memory.aspx). – groverboy Nov 12 '14 at 10:18
  • @Ed.ward, Hi, thanks for you kind offer. My app is 32bit (because the VLC 64bit bindings do not work). Any attempts to analyse by taking subsequent snapshots fail. i just get an error from jetBrains telling me there is not enough memory. I have put in my code to compact LOH using this: GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce; inside a timer that runs every 30 seconds. I traced the timeline back to when the memory started to escalate dramatically and it did so after 27hrs of running. i shall look at the links you have given me. Thank you! – Andrew Simpson Nov 12 '14 at 10:28
  • 1
    As @oleksii noted, there's a gotcha with automatic garbage collection. A process can allocate memory faster than the GC can free up enough *contiguous* space to maintain the process indefinitely. AFAIK the solution is to override the GC's well intentioned nondeterminism. A common case is with COM: use Marshal.ReleaseComObject. Or recycle objects instead of constantly discarding them and creating new ones. – groverboy Nov 12 '14 at 10:37
  • 1
    @groverboy Hi, thanks for your insight. This is all good stuff. i have already made sure I reuse objects as opposed to creating new ones where ever I can. As i am dealing with bitmaps and as i am running a real-time always on-demand app I am using the GC.Collect (every 30 seconds). I know this is not RECOMMENDED but i reasoned because of the nature of the app and also your comment above it would be prudent to do so? Or have I got this completely wrong? Thanks :) – Andrew Simpson Nov 12 '14 at 10:42
  • 1
    @groverboy Live that link you gave me. Very informative.. – Andrew Simpson Nov 12 '14 at 11:05
  • 1
    Smells like unreleased unmanaged resources to me. – Adam Houldsworth Nov 12 '14 at 11:11
  • @AdamHouldsworth Hi Adam, do you mean the EMGU library I am using? – Andrew Simpson Nov 12 '14 at 11:12
  • @AndrewSimpson If you are interoping with anything unmanaged, you need to be hot on what resources that stuff manages (because it'll be in your process) and whether you need to do anything to release the resources when you are finished with them. It's just conjecture on my part, I don't know enough about those libraries to offer targeted advice. – Adam Houldsworth Nov 12 '14 at 11:14
  • @AdamHouldsworth Hi Adam, sorry for my poor previous comment. What I should have said it MUST be emgu as it is the only unmanaged code I am using.. Thank You :) – Andrew Simpson Nov 12 '14 at 11:16
  • 1
    How do you know there are no undisposed objects? To confirm whether the problem is unmanaged memory, see [Identify And Prevent Memory Leaks In Managed Code](http://msdn.microsoft.com/en-us/magazine/cc163528.aspx#S2). A good article that shows how to use WinDbg (not for the fainthearted) is [Investigating Memory Issues](http://msdn.microsoft.com/en-us/magazine/cc163528.aspx). – groverboy Nov 12 '14 at 13:09
  • 1
    Hi, well i have gone through my code and i am disposing of everything. Also, JetBrains indicates objects are being disposed. What the mystery is (at least to me) is why does everything work for 27 hours and dramatically spikes in memory (see 2nd image in my question). The operation of the code is exactly the same. it des not do anything different to what it did doi right from the beginning. Thanks for links i will read this now :) – Andrew Simpson Nov 12 '14 at 13:12
  • 1
    @AndrewSimpson "jetBrains telling me there is not enough memory" - it seems that you are using 32bit windows version, or you really have not enough physical memory to run your app and dotMemory at the same time. Try to run them on x64 windows or add memory in order to get snapshot, I hope snapshot will answer all your questions. What about OOM exception. Even on win x64 [there is only 2Gb of memory available for 32 bit application](http://stackoverflow.com/a/639562/779822). In my experience 32bit app crashes about 1.3-1.5Gb memory usage. – Ed Pavlov Nov 14 '14 at 09:28
  • @Ed.ward Hi, thanks for taking your time to comment on this. i am using 64bit windows and it has 4GB RAM. The app I have created is a 32bit app though. If i add more memory then will I not have to wait longer for the same error to re-occur again? – Andrew Simpson Nov 14 '14 at 09:31
  • 1
    @AndrewSimpson Start profiling without collecting allocations (it reduces dotMemory memory usage). Make every effort to get a snapshot, we should to know, what these 1.5Gb of objects are. – Ed Pavlov Nov 14 '14 at 09:32
  • Hi Again :) I shall take a look at how to disable collection allocations.Thanks for the tip! – Andrew Simpson Nov 14 '14 at 09:33
  • 1
    @AndrewSimpson "If i add more memory then will I not have to wait longer for the same error to re-occur again?" - no, for 32 bit application it will be nothing changed. But dotMemory will be able to take a snapshot :) Do not spend money, just find a computer where you can make a try :) – Ed Pavlov Nov 14 '14 at 09:34
  • @AndrewSimpson https://www.jetbrains.com/dotmemory/webhelp/Profiler_Options.html – Ed Pavlov Nov 14 '14 at 09:35
  • 1
    @AndrewSimpson Another one idea how to force the dotMemory to get a snapshot! Run it on the another computer and use remote profiling https://www.jetbrains.com/dotmemory/webhelp/Starting_Remote_Profiling_Process.html – Ed Pavlov Nov 14 '14 at 09:38
  • @Ed.ward Hi, thanks for all your comments. Just got back from a meeting. i will look at all that you have suggested :) – Andrew Simpson Nov 14 '14 at 09:59
  • 1
    Here's what looks like a similar question, with an erudite answer: [WorkingSet spike just before OutOfMemoryException](http://stackoverflow.com/questions/13866386/workingset-spike-just-before-outofmemoryexception). Good luck! – groverboy Nov 16 '14 at 05:03

0 Answers0