Boxing and UnBoxing

J

Joe

Consider the following code loop:

for(int x = 0; x < 100; x++)
{
string sLoop = "Loop # " + (x+1).ToString();
Console.WriteLine(x);
}

I was told that the (x+1).ToString() was a boxing statement, and would
therefore cause a memory leak because there's no explicit unboxing
statements. Now granted this is a simplistic example, and wouldn't
normally be found in a real-workld application. But it's not uncommon to
see statements such as (x+1).ToString(), so how would you explicitly
un-box this?
 
G

Gabriel Lacatus

Told by who?
I don't believe this, I don't think the garbage collector knows(or cares for
that matter) about boxing and unboxing.
 
M

Michael Bray

Told by who?
I don't believe this, I don't think the garbage collector knows(or
cares for that matter) about boxing and unboxing.

I agree... I'm not 100% sure, but I think the OP's issue here is that an
object will be created for the (x+1) in order to do the ToString. So while
this isn't a memory leak in the true sense of the word, if you were to do
something like this in a tight loop then it could cause memory exhaustion
and the GC to run more frequently, resulting in poor(er) performance.

-mdb
 
L

Laura T.

No boxing/unboxing occures.
Compiler is smart enough to eliminate the sequence into a Int32::ToString()
directly.

Laura.

For curiosity, this is IL listing of your code snippet:

// Code size 42 (0x2a)
.maxstack 3
.locals init ([0] int32 x,
[1] int32 CS$0$0000)
IL_0000: ldc.i4.0
IL_0001: stloc.0
IL_0002: br.s IL_0024
IL_0004: ldstr "Loop # "
IL_0009: ldloc.0
IL_000a: ldc.i4.1
IL_000b: add
IL_000c: stloc.1
IL_000d: ldloca.s CS$0$0000
IL_000f: call instance string [mscorlib]System.Int32::ToString()
IL_0014: call string [mscorlib]System.String::Concat(string,
string)
IL_0019: pop
IL_001a: ldloc.0
IL_001b: call void [mscorlib]System.Console::WriteLine(int32)
IL_0020: ldloc.0
IL_0021: ldc.i4.1
IL_0022: add
IL_0023: stloc.0
IL_0024: ldloc.0
IL_0025: ldc.i4.s 100
IL_0027: blt.s IL_0004
IL_0029: ret
 
G

Gabriel Lacatus

Thumbs up for the framework ! ;)

Laura T. said:
No boxing/unboxing occures.
Compiler is smart enough to eliminate the sequence into a
Int32::ToString() directly.

Laura.

For curiosity, this is IL listing of your code snippet:

// Code size 42 (0x2a)
.maxstack 3
.locals init ([0] int32 x,
[1] int32 CS$0$0000)
IL_0000: ldc.i4.0
IL_0001: stloc.0
IL_0002: br.s IL_0024
IL_0004: ldstr "Loop # "
IL_0009: ldloc.0
IL_000a: ldc.i4.1
IL_000b: add
IL_000c: stloc.1
IL_000d: ldloca.s CS$0$0000
IL_000f: call instance string [mscorlib]System.Int32::ToString()
IL_0014: call string [mscorlib]System.String::Concat(string,
string)
IL_0019: pop
IL_001a: ldloc.0
IL_001b: call void [mscorlib]System.Console::WriteLine(int32)
IL_0020: ldloc.0
IL_0021: ldc.i4.1
IL_0022: add
IL_0023: stloc.0
IL_0024: ldloc.0
IL_0025: ldc.i4.s 100
IL_0027: blt.s IL_0004
IL_0029: ret


Joe said:
Consider the following code loop:

for(int x = 0; x < 100; x++)
{
string sLoop = "Loop # " + (x+1).ToString();
Console.WriteLine(x);
}

I was told that the (x+1).ToString() was a boxing statement, and would
therefore cause a memory leak because there's no explicit unboxing
statements. Now granted this is a simplistic example, and wouldn't
normally be found in a real-workld application. But it's not uncommon to
see statements such as (x+1).ToString(), so how would you explicitly
un-box this?
 
R

Rene

Even though value types don't have object pointers (are not reference
types), methods such as Equals(), GetHashCode() and ToString() (virtual
methods) can be called as non virtual methods (no boxing required)

This is because Syste.ValueType overrides this methods and since you cannot
inherit from a value type the CLR can safely call this methods as non
virtual (no boxing)

Not all ValueType methods behave the same, methods such as GetType() or
MemberwiseClone() will require your value type to be boxed because this
methods are defined directly in the System.Object and (not automatically
overridden).

Other reasons why ValueTypes can be boxed is if you implement an interface
on the ValueType and then cast the ValueType to the interface, this will
cause the ValueType to be boxed.

Concerning the memory leak issue: When a ValueType gets boxed, it will
eventually become unreachable and then the garbage collector will clean it
up so there is no such thing as a memory leak.
 

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