C# class instance with static method vs static class memory usage - c#

How does C#, or other languages for that matter, handle memory allocation (and memory de-allocation) between these two scenarios:
1.) A method on a static class is invoked.
public Program {
Foo foo = Loader.load();
}
public static Loader {
public static Foo load() {
return new Foo();
}
}
2.) A method is invoked on an instance, which then falls out of scope.
public Program {
Foo foo = new Loader().load();
}
public Loader {
public Foo load() {
return new Foo();
}
}
I suppose the static class is loaded, and remains, in memory; whereas the class instance succumbs to garbage collection at C#'s leisure. Are there any pros or cons to these two paradigms? Is there ever a time when you have a class that never needs to be instantiated (i.e. some sort of resource loader or factory), but you use the second methodology anyway to take advantage of garbage collection?
The important part of my question is whether or not the first paradigm, while being conceptually correct in some circumstances, may suffer from holding on to memory unnecessarily.

Your second example doesn't work, so let's explore the real options:
1.) A method on a static class is invoked.
public Program {
Foo foo = Loader.Load();
}
public static Loader {
public static Foo Load() {
return new Foo();
}
}
2.) A static method in a non-static class is invoked.
public Program {
Foo foo = Loader.Load();
}
public Loader {
public static Foo Load() {
return new Foo();
}
}
3.) An instance method is invoked on an instance
public Program {
Foo foo = new Loader().Load();
}
public Loader {
public Foo Load() {
return new Foo();
}
}
The two first are the same. Calling a static method is the same regardless if the class is static or not.
The third option will create an instance of the class on the heap. As the class has no data members, it will only be something like 16 bytes. It will be garbage collected eventually, but due to the small size it doesn't matter much when that happens.
Calling an instance method is also slightly different from a static method. A reference to the class instance is sent along, that you can access through the this keyword. It makes little difference in this case as there is no real data in the object to access.

The second form creates a temporary Loader object (which is very cheap). You will always have to load the Loader class, no matter which approach you choose.
There is very little performance (memory saving) to gain here. You would normally choose for a static member in a static class if there is no 'state' needed outside the methods local vars.

A static method, field, property, or event is callable on a class even when no instance of the class has been created.
http://msdn.microsoft.com/en-us/library/79b3xss3(VS.80).aspx
So in that sense your static methods behaves just as it would if you used it from within a class instance: it is scoped to the type.

I cannot find any sources for this, but from my knowledge of programming, when you refernce a class(non static), it's structure is loaded into memory
Creating an instance of a class just to call a method, would waste a lot of processing power(due to creating an instance, assigning it memory, and the garbage collecting).
Instead of keeping the definition, and then on top of it, an instance. Why not just keep the definition(static).
As long as you don't store any data in static variables, your static method should take up the same amount of memory as your non static method definition. But using a static method, only the method will be kept in memory and be ready to be called whenever you need without creating instances. Where as, if the method is non static, it will need to be instantiated(using up memory and processing power) and the garbage collected(freeing memory and using up cpu) therefore it is definitely better using a static member. Thats what they are there for.

Related

Will a C# class destructor be called when the class contains static fields?

In the following code:
public sealed class Switch
{
public static MyObj s_object = new MyObj();
private readonly SomeObject m_object = new SomeObject();
~Switch()
{
m_object?.Dispose();
}
}
public class Test()
{
Test()
{
Switch switch = new Switch();
switch = null;
...
}
}
When the Test ctor executes, a new Switch object is created then immediately set to null. At some point the GC will dispose of it, calling the ~Switch() destructor in the process. But will that happen when a class contains a static field like s_object and the calling app has not terminated (app domain still loaded)? Static objects persist for the lifetime of the application; does that mean the non-static class containing it will too?
This should be not a problem. Static fields are not related this way to the instance of the defining type in terms of memory representation.
Check this post for more detailed info: How exactly do static fields work internally?
Presence of static fields has no impact on timing when object will be garbage collected (and hence finalized). The instance will be finalized just fine at moment comparable to time it happens without static field.
The only impact static fields have on instances is that static initialization happens before first instance is created thus potentially making creation of first instance slower than the rest.
Note: code in the post shows invalid implementation of finalizer because it refers to other manged object and tries to call method on it. It results in undefined behavior for both cases (with/without static field).

What happens to objects instantiated inside static methods?

I have a static object that looks somewhat like this:
public static class MyStaticObject
{
public static void SomeMethod()
{
MyObject TheObject = new MyObject();
//some long runnning tasks
}
}
As you can see, when SomeMethod() runs, it creates a MyObject. What happens to this instantiated object after the method that created it returns? If SomeMethod() is called again while it's already executing in response to a previous method call, is there going to be a concurrency problem or does each method call instantiate its own MyObject?
TheObject is just a local variable, and it behaves the same way regardless of the fact if the method is static or not.
So after the method returns, the object (if there are no more references to it) is ready for the garbage collector.
And in case of recursion, just another local variable will be created.
If you have C/C++ background, the TheObject is not a static variable in C/C++ terms.

Does static members prevent the instance class from being GC'ed?

Static members are not regarding the instance but the type itself.
But I was wondering :
If I have this class :
public class A
{
...
public static int MyInt{get;set;}
...
}
I can create of course new A()
But my question is :
Does the static member which is "stucked" to the type itself , prevents the instance from being GC'ed ?
Not necessarily. The static member belongs to the class itself, which CLR keeps as a Type object. If the static member was an object of type A, then the static member could keep that particular instance of A from being garbage collected.
public class Example
{
// this particular instance of Example will not be collected
private static readonly Example Default = new Example();
public void Foo()
{
// this instance *can* be collected after Foo returns
Example anotherInstance = new Example();
}
}
This behavior is useful for certain classes which aren't necessarily singletons but do have a "default" behavior that is stateless. One example where I use this is the ParseTreeWalker.Default field in the C# runtime library for the ANTLR 4 project. If you need the default behavior, you can use that instance without creating new objects, but you also have the option of creating your own instances of a class extending ParseTreeWalker to add your own behavior.
No, it does not. This can be easily shown by overwriting the finalizer.

Avoiding static variables with Singleton

A colleague of mine told me that I should never use static variables because if you change them in one place, they are changed everywhere. He told me that instead of using static variables I should use Singleton.
I know that Singleton is for limitation of the number of instances of one class to one.
How can Singleton help me with static variables?
Let's address your statements one at a time:
A colleague of mine told me that I should never use static variables because if you change them in one place, they are changed everywhere.
It seems fairly clear that your colleague means the basic feature of static variables: there is only one instance of a static variable. No matter how many instances of any class you create, any access to a static variable is to the same variable. There is not a separate variable for each instance.
He told me that instead of using static variables I should use Singleton.
This is not good global advice. Static variables and singletons aren't in competition with each other and aren't really substitutes for each other. A singleton is an instance of a class, managed in such a way that only one instance is possible to create. A static variable is similarly tied to exactly one (static) instance of a class, but could be assigned with not only a class instance but any data type such as a scalar. In actuality, to effectively use the singleton pattern, you must store it in a static variable. There is no way to "use a singleton instead of a static variable".
On the other hand, perhaps he meant something slightly different: perhaps he was trying to say that instead of your static class having many different static variables, methods, properties, and fields (altogether, members) that function as if they were a class, you should make those fields non-static, and then expose the wrapping class as a Singleton instance. You would still need a private static field with a method or property (or perhaps just use a get-only property) to expose the singleton.
I know that Singleton is for limitation of the number of instances of one class to one. How can Singleton help me with static variables?
A static class's variables and a singleton are alike in that they both are instantiated once (the former enforced by the compiler and the latter enforced by your implementation). The reason you'd want to use a singleton instead of a static variable inside of a class is when your singleton needs to be a true instance of a class, and not consist simply of the collected static members of a static class. This singleton then gets assigned to a static variable so that all callers can acquire a copy of that same instance. As I said above, you can convert all the different static members of your static class to be instance members of your new non-static class which you will expose as a singleton.
I would also like to mention that the other answers given so far all have issues around thread safety. Below are some correct patterns for managing Singletons.
Below, you can see that an instance of the Singleton class, which has instance (or non-static) members, is created either by static initialization or within the static constructor, and is assigned to the variable _singleton.. We use this pattern to ensure that it is instantiated only once. Then, the static method Instance provides read-only access to the backing field variable, which contains our one, and only one, instance of Singleton.
public class Singleton {
// static members
private static readonly Singleton _singleton = new Singleton();
public static Singleton Instance => _singleton
// instance members
private Singleton() { } // private so no one else can accidentally create an instance
public string Gorp { get; set; }
}
or, the exact same thing but with an explicit static constructor:
public class Singleton {
// static members
private static readonly Singleton _singleton; // instead of here, you can...
static Singleton() {
_singleton = new Singleton(); // do it here
}
public static Singleton Instance => _singleton;
// instance members
private Singleton() { } // private so no one else can accidentally create an instance
public string Gorp { get; set; }
}
You could also use a property default without an explicit backing field (below) or in a static constructor can assign the get-only property (not shown).
public class Singleton {
// static members
public static Singleton Instance { get; } = new Singleton();
// instance members
private Singleton() { } // private so no one else can accidentally create an instance
public string Gorp { get; set; }
}
Since static constructors are guaranteed to run exactly once, whether implicit or explicit, then there are no thread safety issues. Note that any access to the Singleton class can trigger static initialization, even reflection-type access.
You can think of static members of a class as almost like a separate, though conjoined, class:
Instance (non-static) members function like a normal class. They don't live until you perform new Class() on them. Each time you do new, you get a new instance. Instance members have access to all static members, including private members (in the same class).
Static members are like members of a separate, special instance of the class that you cannot explicitly create using new. Inside this class, only static members can be accessed or set. There is an implicit or explicit static constructor which .Net runs at the time of first access (just like the class instance, only you don't explicitly create it, it's created when needed). Static members of a class can be accessed by any other class at any time, in or out of an instance, though respecting access modifiers such as internal or private.
EDIT #ErikE's response is the correct approach.
For thread safety, the field should be initialized thusly:
private static readonly Singleton instance = new Singleton();
One way to use a singleton (lifted from http://msdn.microsoft.com/en-us/library/ff650316.aspx)
using System;
public class Singleton
{
private static Singleton instance;
private Singleton() {}
public static Singleton Instance
{
get
{
if (instance == null)
{
instance = new Singleton();
}
return instance;
}
}
/// non-static members
public string Foo { get; set; }
}
Then,
var foo = Singleton.Instance.Foo;
Singleton.Instance.Foo = "Potential thread collision here.";
Note that the instance member is a static field. You can't implement a singleton without using a static variable, and (I seem to recall - it's been awhile) this instance will be shared across all requests. Because of that, it's inherently not thread safe.
Instead, consider putting these values in a database or other persistent store that's more thread-friendly, and creating a class that interfaces with that portion of your database to provide transparent access.
public static class Foo
{
public static string Bar
{
get { /// retrieve Bar from the db }
set { /// update Bar in the db }
}
}
The whole point of the static modifier is to ensure that the object thus modified is the same wherever it is used as it requires no instantiation. The name originally came about as a static variable has a fixed location in memory and all items referring to it will reference the same memory location.
Now you may wish to use a static field within a class, in which case it exists before the class is instantiated (constructed). There may be instances where you would want this.
A singleton is a different beast. It is a class that is limited to a single instantiation by use of a private constructor and a static property. So in that regard you still can't avoid statics by using a singleton.
To answer the stated question:
It is incredibly stupid (but possible) to create a singleton without a static field.
To do it, you need to use someone else's static field, such as AppDomain.GetData or (in ASP.Net) HttpContext.Application.
Just to answer your question (I hope): Instead of using a static class containing static members like Class1 you can implement the Singleton pattern like in Class2 (please don't begin a discussion about lazy initialization at this point):
public static class Class1
{
public static void DoSomething ()
{
}
}
public static class Class2
{
private Class2() {
}
private Class2 instance;
public Class2 GetInstance(){
if (instance == null)
instance = new Class2();
return instance;
}
public void DoSomething ()
{
}
}
Instead of calling Class1.DoSomething() you can use Class2.GetInstance().DoSomething().
Edit: As you can see there's still a (private) static field inside Class2 holding it's instance.
Edit2 in answer to user966638's comment:
Do I understand you correct that you have code like this:
public class Foo {
private static Bar bar;
}
And your collegue suggests to replace it by this?
public class Foo {
private BarSingleton bar;
}
This could be the case if you want to have different Foo instances where each instance's bar attribute could be set to null for example. But I'm not sure if he meant this what exactly is the use case he is talking about.
Both singleton and static variables give you one instance of a class. Why you should prefer singleton over static is
With Singleton you can manage the lifetime of the instance yourself, they way you want
With Singleton, you have greater control over the initialization of the instance. This useful when initializing an instance of a class is complicated affair.
It's challenging to make static variables thread-safe, with singleton, that task becomes very easy
Hope this helps

Creating an instance of a class in its static constructor - why is it allowed?

Another question on SO inspired me to try this code in C#:
class Program
{
static Program()
{
new Program().Run();
}
static void Main(string[] args) { }
void Run()
{
System.Console.WriteLine("Running");
}
}
This prints "Running" when run.
I actually expected the compiler to complain about this. After all, if the class has not yet been initialized by the static constructor; how can we be sure that it is valid to call methods on it ?
So why does the compiler not restrict us from doing this ? Is there any important usage scenarios for this ?
Edit
I am aware of the Singleton pattern; the point in question is why I can call a method on the instance before my static constructor finishes. So far JaredPar's answer has some good reasoning about this.
It is allowed because not allowing it would be a lot worse. Code like this would deadlock badly:
class A {
public static readonly A a;
public static readonly B b;
static A() {
b = new B();
a = B.a;
}
}
class B {
public static readonly A a;
public static readonly B b;
static B() {
a = new A();
b = A.b;
}
}
You are of course pointing a loaded gun at your foot.
This behavior is documented in the CLI Spec (Ecma 335) Partition II, Chapter 10.5.3.2 "Relaxed guarantees":
A type can be marked with the attribute beforefieldinit (§10.1.6) to indicate that the guarantees specified in §10.5.3.1 are not necessarily required. In particular, the final requirement above need not be provided: the type initializer need not be executed before a static method is called or referenced.
[Rationale: When code can be executed in multiple application domains it becomes particularly expensive to ensure this final guarantee. At the same time, examination of large bodies of managed code have shown that this final guarantee is rarely required, since type initializers are almost always simple methods for initializing
static fields. Leaving it up to the CIL generator (and hence, possibly, to the programmer) to decide whether this guarantee is required therefore provides efficiency when it is desired at the cost of consistency guarantees.
end rationale]
The C# compiler indeed emits the beforefieldinit attribute on a class:
.class private auto ansi beforefieldinit ConsoleApplication2.Program
extends [mscorlib]System.Object
{
// etc...
}
Slightly different question.
How would the compiler prevent you from doing this?
Sure it's very easy to detect in your sample, but what about this sample?
class Program {
static void Fun() {
new Program();
}
static Program() {
Fun();
}
}
The ways in which you can trick the compiler to allow this are virtually endless. Even if the compiler got all of the answers you could still beat it with reflection.
In the end though this is actually legal, if a bit dangerous, code in both C# and IL. It is safe to do this as long as you are careful about accessing static's from within this code. It also is helpful / possibly necessary for certain patterns like Singleton's
Static constructor can initialize only static class members, this is not related to class instances and regular non-static class members.
What you may not realize is that for every class that does not have a non-static constructor, the compiler will generate one. This is different from your static constructor, which when you boil it down into MSIL is little more than a flag telling the CLR "Hey, run this code before you run what's in main()". So, the code of your static constructor is executed first. It instantiates a locally-scoped Program object using the NON-static constructor generated behind the scenes, and once instantiated, Run() is called on the object. Then, because you haven't stored this new object anywhere, it is disposed of when the constructor finishes executing. The main() function then runs (and does nothing).
Try this expansion:
class Program
{
static Program()
{
new Program().Run();
}
public Program()
{
Console.WriteLine("Instantiating a Program");
}
public override void Finalize()
{
Console.WriteLine("Finalizing a Program");
}
static void Main(string[] args) { Console.WriteLine("main() called"); }
void Run()
{
System.Console.WriteLine("Running");
}
}
See what the output is. My guess is that it will look something like this:
Instantiating a Program
Running
Finalizing a Program
main() called
The last two lines may be swapped because garbage collection may not get the chance to destroy the instance before main starts running (GC runs in a seperate managed thread, and so it works on its own time within the lifetime of the process), but the instance IS local to the static constructor in scope, and so is marked for collection before main() starts running. So, if you called Thread.Sleep(1000) in main() before printing the message, GC should collect the object in that time.

Categories