Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I know if I'm about to get an OutOfMemoryException?

Tags:

c#

.net

I have a program that processes high volumes of data, and can cache much of it for reuse with subsequent records in memory. The more I cache, the faster it works. But if I cache too much, boom, start over, and that takes a lot longer!

I haven't been too successful trying to do anything after the exception occurs - I can't get enough memory to do anything.

Also I've tried allocating a huge object, then de-allocating it right away, with inconsistent results. Maybe I'm doing something wrong?

Anyway, what I'm stuck with is just setting a hardcoded limit on the # of cached objects that, from experience, seems to be low enough. Any better Ideas? thanks.

edit after answer

The following code seems to be doing exactly what I want:

Loop 
    Dim memFailPoint As MemoryFailPoint = Nothing
    Try
        memFailPoint = New MemoryFailPoint( mysize) ''// size of MB of several objects I'm about to add to cache 
        memFailPoint.Dispose()
    Catch ex As InsufficientMemoryException
        ''// dump the oldest items here
    End Try
   ''// do work
next loop.

I need to test if it is slowing things down in this arrangement or not, but I can see the yellow line in Task Manager looking like a very healthy sawtooth pattern with a consistent top - yay!!

like image 894
FastAl Avatar asked Aug 25 '11 15:08

FastAl


3 Answers

You can use MemoryFailPoint to check for available memory before allocating.

like image 130
Dan Bryant Avatar answered Nov 11 '22 07:11

Dan Bryant


You may need to think about your release strategy for the cached objects. There is no possible way you can hold all of them forever so you need to come up with an expiration timeframe and have older cached objects removed from memory. It should be possible to find out how much memory is left and use that as part of your strategy but one thing is certain, old objects must go.

like image 1
Otávio Décio Avatar answered Nov 11 '22 07:11

Otávio Décio


If you implement your cache with WeakRerefences (http://msdn.microsoft.com/en-us/library/system.weakreference.aspx) that will leave the cached objects still eligible for garbage collection in situations where you might otherwise throw an OutOfMemory exception.

This is an alternative to a fixed sized cache, but potentially has the problem to be overly aggressive in clearing out the cache when a GC does occur.

You might consider taking a hybrid approach, where there are a (tunable) fixed number of non-weakreferences in the cahce but you let it grow additionally with weakreferences. Or this may be overkill.

like image 1
Logan Capaldo Avatar answered Nov 11 '22 06:11

Logan Capaldo