473,406 Members | 2,707 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,406 software developers and data experts.

Memory GC - loop

Hello,

Would you know what is best practice please between say:

CODE 1:

TimeSpan ts;

for (i=0; i<1000; i++)
{
ts = ...;
blablabla;
}

and

CODE 2:

for (i=0; i<1000; i++)
{
TimeSpan ts = ...;
blablabla;
}
It seems to me they may both impact differently on the GC.
Clearly, I used a timeSpan but it could be anything else.
What do you think is best?
does the GC behaves the same way in both cases?

Thanks.
--
Michael
----
http://michael.moreno.free.fr/
http://port.cogolin.free.fr/
Jan 24 '07 #1
14 3529

In theory Code1 should create one variable that remains in scope for
the entire function and override its contents over and over (unless you
have ts = new TimeSpan() inside the loop), Code 2 would create a new
variable on each iteration of the loop that goes out of scope every
time.
Personally I try not to declare variables inside of a loop, but I never
actually checked how this influences memory usage/runtime behavior.

Sincerely,
Kevin Wienhold

On 24 Jan., 14:06, Michael Moreno <MyFirstName.MySurn...@free.fr>
wrote:
Hello,

Would you know what is best practice please between say:

CODE 1:

TimeSpan ts;

for (i=0; i<1000; i++)
{
ts = ...;
blablabla;
}

and

CODE 2:

for (i=0; i<1000; i++)
{
TimeSpan ts = ...;
blablabla;
}

It seems to me they may both impact differently on the GC.
Clearly, I used a timeSpan but it could be anything else.
What do you think is best?
does the GC behaves the same way in both cases?

Thanks.

--
Michael
----http://michael.moreno.free.fr/http://port.cogolin.free.fr/
Jan 24 '07 #2

One thing is sure:

CODE 2 is slower because it creates new reference to TimeSpan ts in each
loop.

But objects probably disposed same why, because when you set refrence to new
object GC collect old object.

"Michael Moreno" <My*******************@free.frwrote in message
news:mn***********************@free.fr...
Hello,

Would you know what is best practice please between say:

CODE 1:

TimeSpan ts;

for (i=0; i<1000; i++)
{
ts = ...;
blablabla;
}

and

CODE 2:

for (i=0; i<1000; i++)
{
TimeSpan ts = ...;
blablabla;
}
It seems to me they may both impact differently on the GC.
Clearly, I used a timeSpan but it could be anything else.
What do you think is best?
does the GC behaves the same way in both cases?

Thanks.
--
Michael
----
http://michael.moreno.free.fr/
http://port.cogolin.free.fr/


Jan 24 '07 #3
Yes it behaves the same, for 2 very different reasons:

First - unless you use "captured variables" (anonymous delegates),
then the nesting of variables is one of the very few things that is
lost when compiling to IL - since all variables are part of the
preamble (".locals init").

Second - TimeSpan is a struct and is not handled by the GC; in either
case there is *one* memory address (on the stack). When you do " = new
TimeSpan(5)", you over-write that memory. When the method exits the
stack is reclaimed and the variable disappears into the ether. No
objects : no GC.

Marc
Jan 24 '07 #4
It makes no difference whatsoever; e.g.

TimeSpan ts1;
for(int i = 0; i <100; i++) {
ts1 = new TimeSpan(i);
}
for (int i = 0; i < 100; i++) {
TimeSpan ts2 = new TimeSpan(i);
}

compiles to:

.entrypoint
.maxstack 2
.locals init (
[0] [mscorlib]System.TimeSpan span1,
[1] int32 num1,
[2] [mscorlib]System.TimeSpan span2,
[3] bool flag1)
L_0000: nop
L_0001: ldc.i4.0
L_0002: stloc.1
<SNIP>

Local variable names are lost, but notice that span1 and span2 are
both declared method-wide.

Marc
Jan 24 '07 #5
I'm not trying to labor this point, but I think that understanding GC
is *so* imporant that I'll post a 3rd reply on this chain...

ILCODE 2 is slower because it creates new reference to TimeSpan ts
in each loop
MG: no it isn't / there are no references / there is only 1 "ts"

ILBut objects probably disposed same why,...
MG: well, they aren't objects (meaning: reference-types), and even if
they were they aren't "disposed"

ILbecause when you set refrence to new object GC collect old object.
MG: this is *very* misleading, even when talking about reference-type
objects; this would only happen so readily in a reference-counted
world. In a GC world, the old object simply becomes eligible for
collection once dereferenced - that is all you can say for sure. GC
does not run continually - rather there are some complex rules that
make it run periodically with extra focus if memory becomes tight - or
it can be invoked manually, but this is not a good idea unless you
really, really know exactly what you are doing and have profiler
evidence to support this strategy. And code comments detailing it all
;-p

Marc
Jan 24 '07 #6

Thank you for clearing that up, I wasn't sure how the compiler would
handle this kind of code when turning it into IL code.
In the case of a value type it wouldn't make a difference anyways, but
I assumed the question was aimed at objects in general and thought that
in case of a reference type it would.

Sincerely,
Kevin Wienhold

On 24 Jan., 15:07, "Marc Gravell" <marc.grav...@gmail.comwrote:
Yes it behaves the same, for 2 very different reasons:

First - unless you use "captured variables" (anonymous delegates),
then the nesting of variables is one of the very few things that is
lost when compiling to IL - since all variables are part of the
preamble (".locals init").

Second - TimeSpan is a struct and is not handled by the GC; in either
case there is *one* memory address (on the stack). When you do " = new
TimeSpan(5)", you over-write that memory. When the method exits the
stack is reclaimed and the variable disappears into the ether. No
objects : no GC.

Marc
Jan 24 '07 #7
In the case of objects, GC behaves *almost* as you expect. Even if you
nest the variable, it is flattened at runtime into a single stack
variable. I believe that GC will ignore the object currently held in
the stack variable until (at least) the last "read" of that variable
(over *all* iterations) - this is *almost* the same as saying that
each object lives until the end of the loop, but actually I suspect
that if GC ran *right at the start* of a loop (before the variable is
assigned), then the object from the previous loop (still referenced in
the stack) will be retained. All prior objects no longer referenced in
the stack will be eligible for collection.

I don't *think* (happy to be corrected) that the IL wipes the variable
at the end of each loop (the C# validation making that unnecessary).
If you had a long running loop, with a loop variable that is often not
used, but sometimes contains a big object (perhaps a large byte[] on
the LOH), then there may be a case for explicitely setting the
variable to null at the end of each iteration (where it was used) so
that the large opject can be collected early if the next 2754 loop
iterations don't touch that variable. Of course, there is a chance the
compiler might decide to no-op this instruction, but you do what you
can...

Marc
Jan 24 '07 #8
Hi,

"Ivar Lumi" <iv**@lumisoft.eewrote in message
news:OQ**************@TK2MSFTNGP02.phx.gbl...
|
| One thing is sure:
|
| CODE 2 is slower because it creates new reference to TimeSpan ts in each
| loop.

Incorrect, the only difference is that CODE 1 will have ts available AFTER
the for loop. There is no more memory use in the second variant. Only one
instance of TimeSpan is created

| But objects probably disposed same why, because when you set refrence to
new
| object GC collect old object.

That is true but for the incorrect reason. There is only 1 instance so no
new object is created ever. They are disposed the same way but for other
reasons, TimeSpan is a struct so THE GC HAS NOTHING TO DO WITH IT. It's only
when the method call returns that the memory is cleared.

Take a look at http://www.yoda.arachsys.com/csharp/memory.html very good
explanation of memory management in c#
Jan 24 '07 #9
HI,

"KWienhold" <he******@trashmail.netwrote in message
news:11**********************@a75g2000cwd.googlegr oups.com...
|
| In theory Code1 should create one variable that remains in scope for
| the entire function and override its contents over and over (unless you
| have ts = new TimeSpan() inside the loop), Code 2 would create a new
| variable on each iteration of the loop that goes out of scope every
| time.

This has been clearly answer by Marc.

| Personally I try not to declare variables inside of a loop, but I never
| actually checked how this influences memory usage/runtime behavior.

Quite the opposite, you should declare a variable in the inner scope
possible, this will prevent "polution" in the code and the use of the
variable is clearly marked by the scope.
In the OP case, if you declare ts inside the loop it's clear that you only
use it ,well inside the loop. if you declare it outside there is doubts
about if the variable is used AFTER the loop.

My recommendation is to use the tighter scope possible always
--
Ignacio Machin
machin AT laceupsolutions com
Jan 24 '07 #10
Hi,

"KWienhold" <he******@trashmail.netwrote in message
news:11**********************@m58g2000cwm.googlegr oups.com...
|
| Thank you for clearing that up, I wasn't sure how the compiler would
| handle this kind of code when turning it into IL code.
| In the case of a value type it wouldn't make a difference anyways, but
| I assumed the question was aimed at objects in general and thought that
| in case of a reference type it would.

It depends of the interpretation of
ts = .....

if it create a new instance like
ts = new .....

Yes you will create a new instance each time, but even in this case both
codes will be similar, EXCEPT that CODE 1 will be "slower" as it create one
more instance (outside the loop) than CODE 2

Jan 24 '07 #11


On 24 Jan., 16:13, "Ignacio Machin \( .NET/ C# MVP \)" <machin TA
laceupsolutions.comwrote:
Quite the opposite, you should declare a variable in the inner scope
possible, this will prevent "polution" in the code and the use of the
variable is clearly marked by the scope.
In the OP case, if you declare ts inside the loop it's clear that you only
use it ,well inside the loop. if you declare it outside there is doubts
about if the variable is used AFTER the loop.

My recommendation is to use the tighter scope possible always
>From a readability point of view you are certainly right about that,
but the initial question was aimed towards performance issues, in which
case the first implementation would be favorable imho (unless you use
"new" inside the loop, as stated).

Sincerely,
Kevin Wienhold

Jan 24 '07 #12
but the initial question was aimed towards performance issues, in which
case the first implementation would be favorable imho (unless you use
"new" inside the loop, as stated).
Thanks.
Yes there is always a "new" in the loop and I could have put a class
instead of a Timespan.

--
Michael
----
http://michael.moreno.free.fr/
http://port.cogolin.free.fr/
Jan 24 '07 #13
In OPs original code 1, the variable ts isn't instantiated outside the loop.
Thus, it's value will be null. There is no performance penalty other than
the single machine instruction required to set a memory location to 0.

Mike Ober.

"Ignacio Machin ( .NET/ C# MVP )" <machin TA laceupsolutions.comwrote in
message news:Ov**************@TK2MSFTNGP03.phx.gbl...
Hi,

"KWienhold" <he******@trashmail.netwrote in message
news:11**********************@m58g2000cwm.googlegr oups.com...
|
| Thank you for clearing that up, I wasn't sure how the compiler would
| handle this kind of code when turning it into IL code.
| In the case of a value type it wouldn't make a difference anyways, but
| I assumed the question was aimed at objects in general and thought that
| in case of a reference type it would.

It depends of the interpretation of
ts = .....

if it create a new instance like
ts = new .....

Yes you will create a new instance each time, but even in this case both
codes will be similar, EXCEPT that CODE 1 will be "slower" as it create
one
more instance (outside the loop) than CODE 2



Jan 25 '07 #14
"Michael D. Ober" <obermd.@.alum.mit.edu.no.spamschrieb im Newsbeitrag
news:zJ******************@newsread3.news.pas.earth link.net...
In OPs original code 1, the variable ts isn't instantiated outside the
loop. Thus, it's value will be null. There is no performance penalty
other than the single machine instruction required to set a memory
location to 0.

Mike Ober.
Not even that, the variable simply will be not definitly assigned. But the
compiler will optimize the difference away.

Christof
"Ignacio Machin ( .NET/ C# MVP )" <machin TA laceupsolutions.comwrote in
message news:Ov**************@TK2MSFTNGP03.phx.gbl...
>Hi,

"KWienhold" <he******@trashmail.netwrote in message
news:11**********************@m58g2000cwm.googleg roups.com...
|
| Thank you for clearing that up, I wasn't sure how the compiler would
| handle this kind of code when turning it into IL code.
| In the case of a value type it wouldn't make a difference anyways, but
| I assumed the question was aimed at objects in general and thought that
| in case of a reference type it would.

It depends of the interpretation of
ts = .....

if it create a new instance like
ts = new .....

Yes you will create a new instance each time, but even in this case both
codes will be similar, EXCEPT that CODE 1 will be "slower" as it create
one
more instance (outside the loop) than CODE 2




Jan 25 '07 #15

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: Vincent | last post by:
Hi I have a problem with pear DB my code : for ($i=0;$i<100000;$i) { $sql = "select id from table where id=x";
4
by: Don Nell | last post by:
Hello Why is there a memory leak when this code is executed. for(;;) { ManagementScope scope = new ManagementScope(); scope.Options.Username="username"; scope.Options.Password="password";...
4
by: hazz | last post by:
given namespace WindowsService1 { public class Service1 : System.ServiceProcess.ServiceBase......... private void timer1_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { ArrayList...
20
by: jeevankodali | last post by:
Hi I have an .Net application which processes thousands of Xml nodes each day and for each node I am using around 30-40 Regex matches to see if they satisfy some conditions are not. These Regex...
5
by: Aaron Birkland | last post by:
I have a long but straightforward query (on some very large tables) that always ends in 'Memory exhausted in AllocSetAlloc(108)'. Even stranger are some messages that appear in the logfile, such...
23
by: James | last post by:
The following code will create memory leaks!!! using System; using System.Diagnostics; using System.Data; using System.Data.SqlClient; namespace MemoryLeak
30
by: MAG1301 | last post by:
I've detected memory leaks in our huge .NET 1.1 C# application but couldn't localize them directly. So I've reduced the code to the following console application: using System; using System.IO;...
1
by: roadbai | last post by:
Hi all, This is the first time to post question here, hopefully experts of perl here can give me a hand, to be honest, I am kind of new to perl, and I am struggling with the "Out of memory" issue I...
5
by: TimDGCB | last post by:
Hello, I'm writing a python script for Amarok, I communicate with Amarok using DCOP. Now, I have to call DCOP very often and I noticed that every time I make a DCOP call my program keeps...
17
by: christophe.chazeau | last post by:
Hi, I have a problem with a really simple chunk of code which should work but does obviously does not. This chunk of code is just a POC aimed at finding a bug in a larger project in which the...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.