GarbageCollector, Dispose or static Methods? - c#

I developed a few classes last month. They grow big (round 30-40 Methods each class).
I never take a thought of Memory Leaks, GarbageColletor or something like this (I must say this is my first own big project).
Now I have classes with Methods, 15 Classes Round About, each class min. 20 methods. 50% are Linq-Classes in the DAL, 50% BusinessClasses with BusinessLogic. NO Class uses global variables (no need), so theoretically I can make them static classes + methods. At the moment they aren't, I initialize a class object and use the class - and not disposing it.
Where I should start when I be angry of having Memory Leaks etc. when the system runs by ~100 users?

Don't worry about the methods of your classes since they do not consume memory: each method exists only once, in the class definition. What really takes memory is the data contained in the objects in the form of fields.
About disposing objects (I assume .NET here), it is not necessary unless you use unmanaged resources. The garbage collector will take care of freeing all the managed resources (that is, plain objects with their data) when necessary.
If you want more information about the .NET garbage collector and how to deal with memory leaks, you can for example look here: http://www.codeproject.com/KB/dotnet/Memory_Leak_Detection.aspx. But if you are at the start of your project, I would concentrate on getting a clear and maintainable design, rather than on memory management issues.

Whether you can make a class static does not depend on the use of 'global' variables but on the fact if a class uses instance fields (class member variables). If your methods do not use instance data the can be static (and there is a light preference to do so). If all methods are static you can make the class static as well.

Related

Are static methods always held in memory?

My whole development team thinks, static methods are a terrible thing to use.
I really don't see any disadvantages in some cases. When I needed a stateless method before, I always used static methods for that purpose.
I agree with some of their points, e.g. I know they are quite hard to test (although it's not impossible).
What I don't get is, that they claim, static methods are always held in memory and will fill the basic memory usage. So, if you are using 100 static methods in your program, when the program starts all methods are loaded into memory and will fill the memory unnecessarily. Furthermore static methods increase the risk of memory leaks.
Is that true?
It's quite inconvenient to have to create a new instance of a class just to call the method. But thats how they do it right now, the create a instance in mid of a method and call that method, that could be just a static one.
There is no distinction between static and instance methods as far as memory is concerned. Instance methods only have an extra argument, this. Everything else is exactly the same. Also the basic way in which extension methods were easy to add to C#, all that was needed was syntax to expose that hidden this argument.
Methods occupy space for their machine code, the actual code that the processor executes. And a table that describes how the method stores objects, that helps the garbage collector to discover object roots held in local variables and CPU registers. This space is taken from the "loader heap", an internal data structure that the CLR creates that is associated with the AppDomain. Happens just once, when the method first executes, just-in-time. Releasing that space requires unloading that appdomain. Static variables are also allocated in the loader heap.
Do not throw away the big advantage of static methods. They can greatly improve the readability and maintainability of code. Thanks to their contract, they cannot alter the object state. They can therefore have very few side-effects, makes it really easy to reason about what they do. However, if they make you add static variables then they do the exact opposite, global variables are evil.
It's quite inconvenient to have to create a new instance of a class just to call the method. But thats how they do it right now
They are being ridiculous, to be blunt.
As commenter Groo has pointed out, at the native compiled level, an instance method isn't even all that different from a static method. It's just that there's an implicit parameter being passed to the instance method, while with the static method "what you see is what you get".
The runtime may optimize access to a method. It may not JIT-compile the method until the first time it's executed. It may not even load the IL from your assembly into memory until the IL is actually needed. But it can perform these optimizations with static and instance methods equally well.
In fact, forcing all methods to be instance methods is worse than using static method, because it means that for some methods, one is arbitrarily creating an otherwise-useless object. While the runtime may be able to detect the object reference is unused and so cause it to have a minimum lifespan, it can't avoid allocating the object altogether, even a degenerate object will take up some memory while it's alive, and it will add to the cost of garbage collection.
And beyond all that, let's suppose for a moment your colleagues were correct. What would you have gained? Any measurable performance difference at all? Doubtful. Let's face it: managed code, and especially C#, has the potential to hide any number of performance-draining implementation details from us. The main reason we use a managed code language like C# is that we gain so much in productivity and code-correctness, that these possible inefficiencies are well worth it. Most of the time, and especially on modern computers, they are practically invisible.
As it happens, your colleagues are not correct, and it is not in any way beneficial to make into instance methods, methods that otherwise could be static methods. But even if that wasn't the case, to spend time writing obfuscated, unexpressive code to avoid some unmeasured, unproven performance cost is a waste. (And I know no one bothered to compare the actual performance difference, because if they had, they'd have found no improvement in performance by eliminating all static methods).

Should variables be reused to optimize resource utilization?

I am Using Microsoft Visual C# 2010. I have several methods that use a large bitmap for local processing, and each method can be called several times.I can declare a global variable and reuse it:
Bitmap workPic, editPic;
...
void Method1() {
workPic = new Bitmap(editPic);
...
}
void Method2() {
workPic = new Bitmap(editPic.Width * 2, editPic.Height * 2);
...
}
or declare a local variable in each method:
Bitmap editPic;
...
void Method1() {
Bitmap workPic = new Bitmap(editPic);
...
}
void Method2() {
Bitmap workPic = new Bitmap(editPic.Width * 2, editPic.Height * 2);
...
}
The second way is better for code clarity (local variables for local use). Is there a difference in terms of resource utilization?
If you intend to keep the memory allocated to you can use workPic again after the method, you should register it as class variable. If not, you can free memory (always a good idea) by letting it go out of scope.
Allocating one variable doesn't matter much to the framework which manages memory. Only if you recreate a variable inside a tight loop you may benefit by reusing the variable. If you have basic types, you even reuse the same memory. Else, only the reference to the allocated memory is kept, so not that much benefit you have from there.
Note it is very important to Dispose your workPic since now you have a memory leak in the unmanaged memory behind Bitmap. Preferably use using.
Why Global Variables Should Be Avoided When Unnecessary
Non-locality -- Source code is easiest to understand when the scope of its individual elements are limited. Global variables can be
read or modified by any part of the program, making it difficult to
remember or reason about every possible use.
No Access Control or Constraint Checking -- A global variable can be get or set by any part of the program, and any rules regarding its
use can be easily broken or forgotten. (In other words, get/set
accessors are generally preferable over direct data access, and this
is even more so for global data.) By extension, the lack of access
control greatly hinders achieving security in situations where you may
wish to run untrusted code (such as working with 3rd party plugins).
Implicit coupling -- A program with many global variables often has tight couplings between some of those variables, and couplings
between variables and functions. Grouping coupled items into cohesive
units usually leads to better programs.
Concurrency issues -- if globals can be accessed by multiple threads of execution, synchronization is necessary (and too-often
neglected). When dynamically linking modules with globals, the
composed system might not be thread-safe even if the two independent
modules tested in dozens of different contexts were safe.
Namespace pollution -- Global names are available everywhere. You may unknowingly end up using a global when you think you are using a
local (by misspelling or forgetting to declare the local) or vice
versa. Also, if you ever have to link together modules that have the
same global variable names, if you are lucky, you will get linking
errors. If you are unlucky, the linker will simply treat all uses of
the same name as the same object.
Memory allocation issues -- Some
environments have memory allocation schemes that make allocation of
globals tricky. This is especially true in languages where
"constructors" have side-effects other than allocation (because, in
that case, you can express unsafe situations where two globals
mutually depend on one another). Also, when dynamically linking
modules, it can be unclear whether different libraries have their own
instances of globals or whether the globals are shared.
Testing and Confinement - source that utilizes globals is somewhat more difficult to test because one cannot readily set up a 'clean'
environment between runs. More generally, source that utilizes global
services of any sort (e.g. reading and writing files or databases)
that aren't explicitly provided to that source is difficult to test
for the same reason. For communicating systems, the ability to test
system invariants may require running more than one 'copy' of a system
simultaneously, which is greatly hindered by any use of shared
services - including global memory - that are not provided for sharing
as part of the test.
reference: http://c2.com/cgi/wiki?GlobalVariablesAreBad
The main thing to understand here is that field and variable is only holding a reference, the memory will be allocated to the object(s) created by "new".
So in both cases all created bitmap objects need to go through garbage collection.
Difference is that object only referenced in method will be ready to be collected right after method execution, when the object which still have reference in a field will be ready to be collected only when the object containing the field also will be ready to be collected.
The only case when it make sense to introduce the field is when you have the same object reused through the life cycle of the host object.
In cases when you recreate object in the beginning of the method definitely variable is recommended.

Questions about Memory Usage in Windows Phone app

How to reduce the memory usage in my C# Windows Phone apps?
Some instances:
1). To use the method: LockScreen.GetImageUri()
I can either add using Windows.Phone.System.UserProfile; in the top of the cs file.
or add the prefix Windows.Phone.System.UserProfile. in front of it, so that's Windows.Phone.System.UserProfile.LockScreen.GetImageUri()
Which one will use less memory?
2). Consider the scope of the variables, will it release memory more frequently if I break my method into multiple pieces, and run them one by one?
e.g. I need to render some images use WriteableBitmap, each might consume 1MB memory, if I have 10 or more images to render, it might exceed the memory limit soon.
Will it help if I render them in different methods?
3). Which is the better choice: Static or Non-Static?
It seems the static object will persist in the memory whenever the app is "alive" or "running", however, to use a non-static method we need to create an instance of it, which will consume the memory each time we do so (isn't it?).
ADD: If I create an instance of a class object, can I "Dispose" it anyway?
A special case: To use the IsolatedStorageSettings.ApplicationSettings;
I can either use it like:
IsolatedStorageSettings settings = IsolatedStorageSettings.ApplicationSettings;
if (!settings.Contains("IconSet"))
{
settings["IconSet"] = "Set1";
}
or I can also use
if (!IsolatedStorageSettings.ApplicationSettings.Contains("IconSet"))
{
IsolatedStorageSettings.ApplicationSettings["IconSet"] = "Set1";
}
Any difference? (regarding to the memory usage)
4). Deployment.Current.Dispatcher.BeginInvoke(() =>{})
Will this method release the memory it used at all?
Or do I need any special method to release the memory manually? Such as EndInvoke()?
No difference.
Objects like images that use large amounts of memory usually implement IDispose. To ensure that memory is released when it is no longer needed you should be calling dispose on objects when you no longer need the memory. Personally I find an easier way to manage this, is rather than explicitly calling Dispose on an object, wrap it in a using statement e.g.
using(Image myImage = new Image(Myfile))
{
// render myImage
}
People will say declare everything static as it is quicker. Personally I think when you try and declare everything static you're losing all the benefits of .NET as an OO language. Unless performance is absolutely critical, I discourage excessive use of static as in most instances the benefits are negligible and the compromises to your code structure are considerable.
EndInvoke() does not release memory
To answer Max Meng...
There is more than one Image class in the .NET framework. e.g.
http://msdn.microsoft.com/en-us/library/system.drawing.image(v=vs.110).aspx
WPF controls do not implement IDispose. Controls are owned by their parent controls. To dispose memory associated with the control call close on the page when you are done with it.
What is the correct way to dispose of a WPF window?
If IDispose is not implemented in a .NET Framework class that implies either there are no unmanaged or substantial resources associated with the class or alternatively that some other component is responsible for managing its resources.

Garbage Collection in C#

So I'm making a client program for a MySQL database for a class and I have a few variables declared at the top of my form class that I use and reuse throughout the lifespan of the form. Every time the variables get used, I'm simply doing something like:
variableName = new VariableClass();
and then using it, primarily with DataSets/Tables. What I'm wondering is should I be explicitly freeing the memory before making another call to new or does C# take care of that for me?
There is no need to explicitly free .Net objects in C#. It runs on the CLR which is a garbage collected environment and hence the items will be cleaned up for you.
That being said ... it's unclear from your question if you are allocating these as fields or locals. If you are allocating them in fields and only using them in one function then you should move that declaration to a local. While the memory won't leak you will be holding onto the objects for significantly longer than is needed. This unnecessarily increases the memory footprint of your application.
It depends upon what the class of the variables does. If it uses resources that require disposal or if it uses unmanaged resources, you should implement IDisposable and ensure that they are disposed of correctly. If not, you can rely on the garbage collector to do its thing.

.Net Memory Management Issue : Objects Stuck in Generation 2

I have profiled my App w/ VS2010 profiler, with object lifetime collection enabled.
I was heavilly surprised to see that most instances of a particular struct named "Record" are collected by the GC as Gen 2 instances. I am very upset, as instances of "Record" struct should live less than 500ms each (theoretically).
These structs are simple time series data of 6xInt32 or so, that are read on the flow, Queued/Dequeued in a Queue having a size of 1000, passed to a processor that fires some logic depending on those few millions "Records" sequentially. I do not need to keep more than 50 records at a time.
So my question is : Why could these object live long enough to mainly end up as Second Generation references, and what could I do to ensure they REALLY get dumped off after each computation.
EDIT :
I am asking this because I have noticed a drastic performance dropdown for bigger sample sizes (i.e Records Numbers) : if N take T minutes, 2N takes 2,5T minutes or so, and so on. So there is obviously a leak somewhere.
EDIT 2 :
My Bad : Creating a struct instance cannot cause a garbage collection
I've changed it to classes and did not notice any significant improvement so far.
I'll run the profiler again with classes this time not structs) and see what it gives
EDIT 3 :
Many answers suspect Boxing/Unboxing to take place somewhere.
I DO use typed generic collections and typed Queues. And "Records" are never attached to any class as members. They are individually handled by events.
The ex-Struct (Now Class) implemented an interface and was casted by it when called (this is rather common usage) and I dropped off that interface. No improvement.
EDIT 4 :
I have run again the profiler, replacing struct by class. I have the same results : most instances of CLASS "Record" still end up being collected as Gen2 instances
EDIT 5 :
Producers of the Record classes are many parallel BackGroundWorkers (Byte Readers), and there is one Consumer Thread that dispatches the Records to other methods after performing a few checks. Besides I use Events and Delegates to communicate between the different parts. I do not unregister those events because they are useful all along the process (I may be wrong on that point)
If you stored them just as local variables (which may or may not be possible depending on your scenario) they will never end up on the heap at all.
If that's possible, I recommend trying that. You might get a more in depth response, if you post a code sample.
As a sanity check, are you forgetting to unregister static events, or using some other class that may be doing this (some classes fix this via Dispose)?
Also have you looked into the possibility of using the Flyweight pattern?
Edit- Since you now say you are doing something with events, this is highly likely to be a cause of your issues. Are you forgetting to unregister the events?
If you are "heavy" on memory use, and you are using C# 4.0, you could try the "server" GC. Merge your app.config (or web.config) with:
<configuration>
<runtime>
<gcServer enabled="true"/>
</runtime>
</configuration>
(with merge I mean that if you already have some of these sections, use them, otherwhise create them. "configuration" is the first level element of the app.config). This is better for some apps (apps that don't need heavy interaction with the user)
They end up as Second Generation because the GC just decided not to garbage collect them. I don't think it is really a problem to worry about. If you really wanted to you could just reuse the 1000 objects instead of continuously creating new ones. This would make it so that these objects wouldn't need to get garbage collected. You could force Garbage collection to ensure the objects "REALLY" get dumped but that would degrade performance as GC is an expensive operation or so I am told.

Categories