Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / .NET Framework / Performance / December 2005

Tip: Looking for answers? Try searching our database.

Memory Usage - Return Type

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Zeeshan Gulzar - 22 Dec 2005 04:25 GMT
Is there any difference in following two codes, regarding memory consumption
as well as Performance

ArrayList  x = GetArrayList();

ArrayList GetArrayList()
{
    ArrayList b = new ArrayList();
    // Store some works in ArrayList b
    return b;
}

-----------------------------------------------------

ArrayList  x = new ArrayList()
GetArrayList(ref x);

void GetArrayList(ref ArrayList x)
{
    // Store some works in ArrayList x
}
-----------------------------------------------------

Also, is there any machanism to remove only above ArrayList object from
memory explictly when this is no more required. like delete keyword in C++.

Thanks in advance.
Jon Skeet [C# MVP] - 22 Dec 2005 06:28 GMT
> Is there any difference in following two codes, regarding memory consumption
> as well as Performance
[quoted text clipped - 17 lines]
>      // Store some works in ArrayList x
> }

Well, the easiest thing to do would be to test it. Note that if you're
only adding things to the ArrayList, you don't need to pass x by
reference. See
http://www.pobox.com/~skeet/csharp/parameters.html

The performance difference, if any, will be tiny. You should always
design your classes for readability and maintainability first - only
consider micro-optimising performance in this way after you've proved
you've got a problem. In this case, returning the ArrayList sounds like
the better approach, although it would depend on the exact situation.

> Also, is there any machanism to remove only above ArrayList object from
> memory explictly when this is no more required. like delete keyword in C++.

No. You *can* call the garbage collector (or at least ask it to run)
but it's almost always a bad idea. Just let it get collected in the
course of time.

Signature

Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet   Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too

Zvonko Keber - 22 Dec 2005 08:02 GMT
The difference would be that in the first example, two objects are created -
one "outside" the function (ArrayList x), and the other ArrayList is created
inside the GetArrayList. When the function finishes, ArrayList B is copied
to the X, and then the reference to the ArrayList B is lost (object still
exists, but it's ready for garbage collection).

In the second example, only one object is created: the one inside
GetArrayList. And when the function finishes, only reference to the object
is returned to the X. Reference to the object is not lost although the
function exited and will not be collected during GC. Therefore you saved
some little time on copy operation.

Theoretically this could be a problem on huge objects (big arraylists,
bitmaps,...) and you should test it before you decide.

The only "delete" would be X = null; This virtually frees up some memory
space, bu it actually tells GC to remove it during next garbage collection,
and works only for objects.

There are some special cases where you need to delete the object created
(for example when working with GDI) but that is usually explicitly well
documented.

> Is there any difference in following two codes, regarding memory
> consumption
[quoted text clipped - 25 lines]
>
> Thanks in advance.
Zvonko Keber - 22 Dec 2005 08:06 GMT
Sorry, correction:

In second example, object is created OUTSIDE the function, and therefore
there is no copy operation.

> The difference would be that in the first example, two objects are
> created - one "outside" the function (ArrayList x), and the other
[quoted text clipped - 48 lines]
>>
>> Thanks in advance.
Jon Skeet [C# MVP] - 22 Dec 2005 08:08 GMT
> The difference would be that in the first example, two objects are created -
> one "outside" the function (ArrayList x), and the other ArrayList is created
[quoted text clipped - 10 lines]
> Theoretically this could be a problem on huge objects (big arraylists,
> bitmaps,...) and you should test it before you decide.

Bitmaps and ArrayLists are both reference types - however large they
are, there won't be any performance penalty in terms of returning them
(whether it's by a return value or an output parameter).

I don't know whether you meant that or just that if the ArrayList
doesn't become eligible for GC at some stage, it could be a problem.
I'm assuming that the OP does want the ArrayList at the point at which
the method returns - after that it's up to him to determine the
lifetime of it.

> The only "delete" would be X = null; This virtually frees up some memory
> space, bu it actually tells GC to remove it during next garbage collection,
> and works only for objects.

No, it doesn't tell the GC to remove it. It just means that that
particular variable doesn't hold a reference to the object any more.
It's very, very rarely worth setting a variable to null for the
purposes of garbage collection.

> There are some special cases where you need to delete the object created
> (for example when working with GDI) but that is usually explicitly well
> documented.

That's not actually deleting objects - that's disposing them so they
can release unmanaged resources. Calling Dispose does *not* free the
memory associated with an object.

Signature

Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet   Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too

Zvonko Keber - 22 Dec 2005 08:48 GMT
> Bitmaps and ArrayLists are both reference types - however large they
> are, there won't be any performance penalty in terms of returning them
[quoted text clipped - 4 lines]
> the method returns - after that it's up to him to determine the
> lifetime of it.

Working with huge objects is much faster if you pass them between functions
by reference. Especially when there are many huge objects, and many "passing
around".

>> The only "delete" would be X = null; This virtually frees up some memory
>> space, bu it actually tells GC to remove it during next garbage
[quoted text clipped - 5 lines]
> It's very, very rarely worth setting a variable to null for the
> purposes of garbage collection.

An object becomes eligible for GC once when all it's references are lost
(set to null). In Zeeshan's exmaple, once is enough. Also, no matter if the
variables are set to null or not, once the function exists all it's objects
are ready for GC because there are no more references to them.
Jon Skeet [C# MVP] - 22 Dec 2005 09:08 GMT
> > Bitmaps and ArrayLists are both reference types - however large they
> > are, there won't be any performance penalty in terms of returning them
[quoted text clipped - 8 lines]
> by reference. Especially when there are many huge objects, and many "passing
> around".

I think you misunderstand reference types, or what pasing by reference
means. If I create an ArrayList and add a million elements to it, then
call a method using a variable with a reference to the ArrayList as a
parameter, the only data which is passed is the reference. Note that
this is not passing *by* reference.

See http://www.pobox.com/~skeet/csharp/parameters.html

To give a concrete example:

using System;
using System.Collections;

class Test
{
   static void Main()
   {
       ArrayList al = new ArrayList();
       
       for (int i=0; i < 1000000; i++)
       {
           al.Add ("Hello");
       }
       ShowCount(al);
   }
   
   static void ShowCount(ArrayList list)
   {
       Console.WriteLine (list.Count);
   }
}

The call to ShowCount here is *not* expensive, and would be no cheaper
(actually very slightly more expensive, I believe) if you made "list" a
reference parameter instead of a value parameter.

> >> The only "delete" would be X = null; This virtually frees up some memory
> >> space, bu it actually tells GC to remove it during next garbage
[quoted text clipped - 8 lines]
> An object becomes eligible for GC once when all it's references are lost
> (set to null).

Well, there's a difference between a reference and a variable. There
don't need to be any variables involved for an object to still be
alive. For instance:

new ArrayList().Add("Hello");

During the call to Add (within subtle limits which I won't go into
right now), the object still isn't available for garbage collection,
despite there being no actual *variables* with references to the
ArrayList.

> In Zeeshan's exmaple, once is enough. Also, no matter if the
> variables are set to null or not, once the function exists all it's objects
> are ready for GC because there are no more references to them.

I assume you meant "exits" rather than "exists" - that confused me for
a bit :)

What I assume you really mean is that the local variables and
parameters of a method are only used as GC roots while the method is
executing.

Signature

Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet   Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too

Zvonko Keber - 22 Dec 2005 09:41 GMT
> The call to ShowCount here is *not* expensive, and would be no cheaper
> (actually very slightly more expensive, I believe) if you made "list" a
> reference parameter instead of a value parameter.

Yes, but... :-)
Which of these would be more expensive (performance and memory)?

Bitmap bmp = new Bitmap(1000, 1000);
for(int y = 0; y<100000; y++)  bmp = Replace(bmp);
...
static Bitmap Replace(Bitmap b)
{
   Bitmap bmp = b;
   //do some work with bmp
   return bmp;
}
------------------- OR -------------------
Bitmap bmp = new Bitmap(1000, 1000);
for(int y = 0; y<100000; y++) Replace(ref bmp);
...
static void Replace(ref Bitmap b)
{
   //do some work with b
}

My real-world example is huge and it makes sense, but it comes
down to this nonsense of an example.

> new ArrayList().Add("Hello");
>
> During the call to Add (within subtle limits which I won't go into
> right now), the object still isn't available for garbage collection,
> despite there being no actual *variables* with references to the
> ArrayList.

Okay, but after that particular line, there are no more references to the
arraylist,
although object is still alive and kicking in memory, but it will be
collected during next GC.
Together with all string objects inside the arraylist. Right?

>> In Zeeshan's exmaple, once is enough. Also, no matter if the
>> variables are set to null or not, once the function exists all it's
[quoted text clipped - 3 lines]
> I assume you meant "exits" rather than "exists" - that confused me for
> a bit :)

Yes, sorry :-)
Jon Skeet [C# MVP] - 22 Dec 2005 10:00 GMT
> > The call to ShowCount here is *not* expensive, and would be no cheaper
> > (actually very slightly more expensive, I believe) if you made "list" a
[quoted text clipped - 23 lines]
> My real-world example is huge and it makes sense, but it comes
> down to this nonsense of an example.

Well, there's no point in making the first version return anything. It
would be most efficiently (and readably) written as:

static void Replace (Bitmap b)
{
   // Do some work with b
}

As it is, the second version may well be more expensive than the first,
depending on exactly what the method does. Parameters should only be
passed by reference when they actually need to be - when the value of
the parameter is changed (which it isn't in this case, even though the
object it refers to may be modified).

> > new ArrayList().Add("Hello");
> >
[quoted text clipped - 6 lines]
> arraylist, although object is still alive and kicking in memory, but it
> will be collected during next GC.

Yes - but only *after* the Add method has finished. That's the
important thing in the example.

> Together with all string objects inside the arraylist. Right?

Actually, the string object (there'd only be one, with lots of
references) wouldn't be eligible for garbage collection, as interned
strings aren't garbage collected until the AppDomain they live in is
unloaded.

Signature

Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet   Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.