views:

60

answers:

6

Hello there!

Out of pure curiosity, is there a way to free the memory used by a StringBuilder, other than the obvious MyBuilder = New StringBuilder and MyBuilder.Remove(0, Length) (although I guess the later wouldn't free anything, would it?)

Thanks!
CFP.

+2  A: 

The best way is to leave it fall out of scope and the GC will take care of the memory.

Darin Dimitrov
What about affecting it to a new object? Will that do anything more than just letting it fall out of scope?
CFP
Depends what you are going to do with the initial pointer. Right now I am feeling like guessing your code, so in order to be more precise show your code so that we have a real base for discussion.
Darin Dimitrov
+1  A: 

You can either let it fall out of scope or Remove(0, Length) and then set Capacity to 0 (I think it frees the extra memory if you set Capacity to 0, but I am not entirely sure).

Razvi
That does the exact opposite, it uses *more* memory. The internal array is recreated.
Hans Passant
Doesn't it create an array with size 0 and lets the previous array go out of scope?
Razvi
Yes, but that doesn't mean anything. That previous array is still there, taking up space in the garbage collected heap. Until the garbage collector runs some time later.
Hans Passant
I believe it sometimes is better: in case other variables reference the object and you want to clear what is stored in it and free the internal memory.
Razvi
@Hans: But I suppose what Razvi could be getting at is that if the `StringBuilder` has grown to a certain size and is going to remain *in* scope (e.g., if it belongs to a class or is used in such a way that it will stick around for some time), it might make sense to change its state so that its members that are taking a lot of space (i.e., its internal array) can be collected, while the `StringBuilder` itself sticks around. Am I right, @Razvi?
Dan Tao
Agreed, it would make sense in that particular scenario.
Hans Passant
Yes, that is the case I was referring to.
Razvi
A: 

The way you "free memory" for any object in .NET is to let the GC take care of it.

In the case of a StringBuilder, just set the instance to Nothing* and let it be.

I think you might be confused about what it means to "dispose" of objects in .NET. The purpose of the IDisposable interface is to provide a mechanism by which objects can release access to some shared resource, e.g., file streams. Calling Dispose is not the same as releasing memory. Since a StringBuilder does not access any shared resources, it does not need to implement IDisposable.

If you must force memory to be freed, that's what GC.Collect is for. But honestly, I've never encountered a scenario where it made sense to call that yourself (as opposed to letting the GC decide when it makes sense to perform a collection).

*I am assuming it's a class-level variable. If it was only a local variable to begin with, there's no need to set it to Nothing as it will soon fall out of scope anyway.

Dan Tao
Sure, using the term dispose wasn't really appropriate.
CFP
+1  A: 

You are right, using the Remove() method just resets an internal index, it doesn't do anything with the internal array. Not explicitly managing memory is a key property of the .NET framework, the garbage collector sorts it out automatically.

Technically you can by calling GC.Collect(). That is however almost always a Really Bad Idea. Yes, you'll make the StringBuilder instance and its internal array disappear, providing there are no references left to it. But it also promotes other objects in your program too early. Which means they'll stick around longer than necessary, your program will eventually use more memory.

Hans Passant
+1  A: 

You could always use MyBuilder = Nothing, but I usually just let them fall out of scope.

Sonny Boy
+1  A: 

Easy solution: I agree that it may be best, and easiest, to simply let the garbage collector take care of it by letting your string builder go out of scope.

stringBuilder = Nothing

Explicit solution: In newer versions of the .NET framework, the StringBuilder class actually has a Clear method that removes all characters in the string builder. (Alternatively, you can set the Length property to 0.)

Ultimately, you can set the Capacity property to 0. (Note that Capacity must not be less than than Length, which is why you first need to clear the string builder.)

stringBuilder.Clear()
stringBuilder.Capacity = 0
stakx