About Best Coding style of c#

K

kiplring

List<string> effectList = new List<string>();
effectList.Clear();
effectList = null;

using (List<string> effectList = new List<string>())
{
}

If there are so many calls, I should save as much memory as I can.

If I want to allocate & release some NOT "disposable" elements, is it
more preferable to do clear and null allocation after use?

or use it with using phrase?

or just leave it alone?

Of course I don't want to coding "disposable" library by my self.
 
B

Barry Kelly

kiplring said:
List<string> effectList = new List<string>();
effectList.Clear();
effectList = null;

You don't need to call Clear() if you're going to null it out on the
next line.
using (List<string> effectList = new List<string>())
{
}

Note that this won't work. The nearest equivalent is:

---8<---
{
List<string> effectList = new List<string>()
}
--->8---

.... since List said:
If there are so many calls, I should save as much memory as I can.

If I want to allocate & release some NOT "disposable" elements, is it
more preferable to do clear and null allocation after use?

If you have a long-lived frame on the stack, and it keeps a large chunk
of memory alive, then it makes sense to null it out. For example:

A() calls
B(), which loops and calls
C(), which loops and calls
D() which loops

where A() looks like:

A():
Allocate memory for a, which is big
Do stuff with a
B()
if (x)
Do stuff with a

Here, the stack frame for A() is going to last for a long time, and the
JIT compiler might not free up 'a' automatically if it can't figure out
'x'. If:

1) The object graph being pointed to by 'a' is big, as in a significant
fraction of your total memory usage, and
2) you know before calling B() that x will be false,
3) it may be useful then to set 'a' to null.

The graph pointed to by 'a' won't be collected until the next GC. If the
only thread running is your thread, and the functions B, C and D don't
allocate memory or only allocate a little, chances are a GC won't even
happen.
or use it with using phrase?

or just leave it alone?

With respect to disposal, it's much more important to focus on actual OS
resources, such as FileStreams and the like. For most little bits of
memory, it isn't worth the trouble to worry about.

If you're concerned about these things, it's best to profile your
application. Write it in the most natural way, and profile it later.
That way, you build up experience that can help you tune things. You
don't need extra tools to profile memory usage. Performance Monitor can
tell you how much time is being spent in GC, to find out if memory
allocation is a speed hog. SOS (Google ".load sos") along with
"!dumpheap -stat", "!dumpheap -type <type>" and "!gcroot" can help track
down what kinds of objects are alive, and where they're being kept alive
from, if you find out that too much memory seems to be allocated.

In general, it isn't worth the effort to micromanage individual memory
allocations below the 80 KB limit. Above 80 KB, (i.e. the total size of
an individual allocation exceeds 80 KB, such as "new byte[100000]") the
chunks of memory are allocated from the large object heap and don't get
collected until gen2 collections. For this reason, it can make sense to
pool such large allocations.

-- Barry
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top