Running out of virtual memory

Antoine

Regular
Joined
Aug 12, 2003
Messages
58
Location
The Netherlands
Dear all,

I have a strange problem, my vb.net application completely runs out of vm, this can exceed 1 GB, since this application constantly runs on a server, windows returns an error after several hours.

The strangest thing is that gc.collect() doesn't seen to work. Does anybody know how to clear up the vm properly ?

Thanks in advance !
Antoine
 
What is your application doing? What kind of resources is it allocating?

GC.Collect will only free up unused resources - if you still have a reference to a variable then GC.Collect will not be able to reclaim the memory.
 
I think the problem is in 4 array's. I use them to store information (duh ;)), and it is constantly ReDim'ed (bigger and smaller) with Preserve option. I think that this is the problem. This can be possible ? Does GC.Collect do something with arrayvariables that are not used anymore ?

Regards,
Antoine
 
ReDim is a misleading, overly-convenient feature. It is not a smart way to manage memory, unless used very carefully. Each time you perform a ReDim, with or without the Preserve option, a new array is created (Preserve specifies that all elements that can fit into the new array should be copied over). It isn't necessarily your only problem, but it certainly isn't helping.

So, for example, if you have a somewhat large array of integers (say 1000), it will take up 4000 bytes. Every time the amount of data you need changes, you decide to save memory by ReDimming to a smaller or larger array so that you only hold as much memory as you need. You end up redimming to 900, then 800, then 1100, which is only 100 more integers than you started with, but if the garbage collector doesn't get a chance to make its rounds all those old arrays pile up, so you end up with three extra arrays floating around (the total of the four arrays would be 15200 bytes, compared to the original 4000 bytes). Besides that, each time you do a ReDim Preserve, all of the data needs to be copied.

This is hardly an efficient way to run things. So, what do we do? For starters, when your need for memory decreases, don't create a new, smaller array unless you aren't going to need the extra space for a long time and the difference is huge. Also, try to predict how much memory you are going to need. If you know you will usually need around 1000 integers, maybe create an array of 1500 integers so you have some breathing room before you need to create a larger array.

But of course, all this coding to be more memory efficient is a pain, which is why Microsoft already did it for you. If you are using VS 2003 there is the ArrayList class, though it is not very efficient with memory when used for structures or primitive types like Integer and Boolean. In VS 2005 we have the generic List class which maintains an array for you and manages the array's memory for you, and is used with array-like syntax.
Visual Basic:
'Create a list
Dim MyInts As New List(Of Integer)
'Add some data
MyInts.Add(1)
MyInts.Add(2)
MyInts.Add(3)
 
'Now we can examine that data as though we were using an array:
Dim RetrievedValue As Integer = MyInts(2) ' Get value
MyInts(0) = 4 ' Set value
 
Hello marble eater,

Hmm, sounds interesting what you write there. My software is also constantly connecting and disconnecting to ethernet devices. And I found out that when I disable the communication part and simply let the array's be filled and emptied without comm's my VM stays decently on 19k something. And doesn't even move a single 4 kB. So OR the problem is in the comm's part itself OR due to the comm's part the GC.collect doesn't work properly. Anyway, if you call gc.collect the program immediatly does a gc ? Or it still waits till it has time to do so ?

Thanks !
Antoine
 
Cags said:
In most cases calling gc.Collect is not a good idea. It's pretty intelligent and when left to it's own devices it is pretty efficient.

I think I found the problem :D:D, it was in my TCP/IP connect routine, I changed it a little and now my memory stays under 24MB :p

Thanks for all your input :)
 
To elaborate on the GC.Collect method, Cags is right on the money. The garbage collector is designed in a manner that is optimized for best performance when the GC is left to its own devices. For example, an important aspect of .Net garbage collection is the use of generations. Each time a garbage collection is performed objects are "aged" a generation. The majority of garbage collections only collect objects from the most recent generation, which means that if you force collections you are pre-maturely aging objects and actually delaying their collection.
 
Back
Top