Services & Resources / Wolfram Forums
-----
 /
MathGroup Archive
2003
*January
*February
*March
*April
*May
*June
*July
*August
*September
*October
*November
*December
*Archive Index
*Ask about this page
*Print this page
*Give us feedback
*Sign up for the Wolfram Insider

MathGroup Archive 2003

[Date Index] [Thread Index] [Author Index]

Search the Archive

Re: What Happens to Garbage in Mathematica?

  • To: mathgroup at smc.vnet.net
  • Subject: [mg44092] Re: What Happens to Garbage in Mathematica?
  • From: "Steven T. Hatton" <hattons at globalsymmetry.com>
  • Date: Wed, 22 Oct 2003 03:24:51 -0400 (EDT)
  • References: <bm84s2$fug$1@smc.vnet.net> <bmg0nf$e9t$1@smc.vnet.net> <bmj2j5$pqs$1@smc.vnet.net> <bmqqao$rjs$1@smc.vnet.net> <bmt7tc$857$1@smc.vnet.net> <bn2imm$o14$1@smc.vnet.net>
  • Sender: owner-wri-mathgroup at wolfram.com

Olaf Rogalsky wrote:

> "Steven T. Hatton" wrote:
[...]
> This is a bit too unspecific to comment on it.

If I could better define what I'm talking about, I would probably be able to
avoid it.  This is the kind of thing that I write off as a minor anoyance
and otherwise ignore.  I *will* add that the Class package from Dr. Mäder
acts very strangely in this regard, and virtually requires the kernel to be
restarted after every change to a class.
[...]
> Yes, you are constructing a new Graphics3D object with 3 copies of "p2",
> which are not memory shared. In the following example things are
> apparently different:
> 
> In[1]:=  imax = 10000;
>          b = Table[Null, {i, imax}];
>          MemoryInUse[]
>          a = Range[10000000];
>          MemoryInUse[]
>          Do[b[[i]] = a, {i, 1, imax}];
> Out[3]=  2360528
> Out[5]=  42362096
> Out[7]=  42403104

I ran this repeatedly and noticed none of the previously allocated memory
seemed to be given back.  I.e., 

Clear[imax, b, a, i]
imax = 10000;
b = Table[Null, {i, imax}];
MemoryInUse[]
a = Range[10000000];
MemoryInUse[]
Do[b[[i]] = a, {i, 1, imax}];
MemoryInUse[]

Out[4]=
2185960

Out[6]=
42187456

Out[8]=
42228464

....

Out[12]=
42233040

Out[14]=
82234144

Out[16]=
82275152

....

Out[20]=
82276632

Out[22]=
122277320

Out[24]=
122317912

I then tried 
Unprotect[Out];
(Out[#] =.) & /@ Range[24] discovered my memory was returned.  It seems not
to matter whether I run the code from within a Module or not. 
Interestingly, I tried the following with different results from thoes
above:

(*First I modified the original code a bit.*) 

 k = 2^10;
imax = k;

memTest[imax_] := Module[{b, a, m0, m1, m2},
  Print[m0 = MemoryInUse[]];
  b = Table[Null, {i, imax}]; 
  Print[m1 = MemoryInUse[]];
  a = Range[2^21];
  Print[MemoryInUse[]];
  Do[b[[i]] = a, {i, 1, imax}];
  Print[m2 = MemoryInUse[]];
  Print[{"m2-m0 = ", m2 - m0, " m2-m1 = ", m2 - m1 }];
];

(*Demonstrate the previous result when run from the In[] prompt:*)


memTest[imax]
2074664
2092552
10481344
10481344
{m2-m0 = , 8406680,  m2-m1 = , 8388792}

memTest[imax]
10477736
10481832
18870544
18870544
{m2-m0 = , 8392808,  m2-m1 = , 8388712}

memTest[imax]
18866840
18870936
27259648
27259648
{m2-m0 = , 8392808,  m2-m1 = , 8388712}

(* Run the same Module 100 times in a Do-loop*
 * Note the results are virtually invariant over the entire run.
 * The fact they are not identical is a bit puzzling, but I'm not overly 
 * concerned about that right now.
*)

Do[Print[MemoryInUse[]]; memTest[imax];i++,{100}]


{m2-m0 = , 8392784,  m2-m1 = , 8388712}
27253768
27255416
27259488
35648200
35648200
{m2-m0 = , 8392784,  m2-m1 = , 8388712}
27253768
27255400
27259472
35648184
35648184
{m2-m0 = , 8392784,  m2-m1 = , 8388712}
27253768
27255440
27259512
35648224
35648224
{m2-m0 = , 8392784,  m2-m1 = , 8388712}
27253768
27255424
27259496
35648208
35648208
{m2-m0 = , 8392784,  m2-m1 = , 8388712}
27253768
27255440
27259512
35648224
35648224
{m2-m0 = , 8392784,  m2-m1 = , 8388712}

> 
> Here, "a" roughly takes 40MB, whereas "b" only eats up 40kB, though "b"
> consists of 10000 copies of "a". Actually "b" has not 10000 copies of "a",
> but 10000 references to the value of "a", which is much cheaper. To
> achieve the same effect in your example, one has to do something like
> this:
> 
> g = Graphics3D[
>       Join[{Red,PointSize[0.02],Line[{p1,dummy,p3}],Line[{p4,dummy,p5}]},
>         Point/@{p1,dummy,p3,p4,p5}]]
> g[[1, 3, 1, 2]] = p2;
> g[[1, 4, 1, 2]] = p2;
> g[[1, 6, 1]] = p2;
> Show[g]

Thanks. I'll have to experiement with that.

> No, a, b and c directly refernce the memory locations, which were bound to
> reallyLongVariableName, when the assignment was made. I drawe a picture
> for you (rectangles denote memory locations, adjacent rectangles dentote
> adjacent memory locations, the content of a rectangle denotes the content
> of that memory location, an arrow denotes the addresses of the memory
> location of the object the arrow is pointing to):

This is what I expected.  I was merely being pedantic to ensure something
strange wasn't going on.
> 
> 
>> >> It would seem that if I were to assign the return value of
>> >> RotateShape[] to lna like this: lna = RotateShape[ln, 2, 2, 2], I
>> >> would create a dirty chunk of memory which will require housekeeping
>> >> before it can be reused.
>> >
>> > I don't understand you here.
>> 
>> If I have a complex shape which is transformed by the above rotation
>> function, the location of the original coordinate values will not be
>> available until garbage collection is run.  Correct?
> 
> Double no :-). No, "ln" still refernces the orignal shape, so its memory
> can't be reused. And no, Mathematica doesn't garbage collect at all. If
> the unrotated shape eventually becomes unreferenced by all live objects,
> Mathematica automatically detects this, and the memory immediately will be
> given back to you:

I should have read your other message before responding to this one.  You
seem to have already addressed this issue.
 
> a=0;                              +---+
>                                   I 0 I <--+
> +------------------------+        +---+    I   +---+   +---+
> I"reallyLongVariableName"I                 I   I"a"I   I"b"I
> +------------------------+        +---+    I   +---+   +---+
> |          o-------------+--+     I 1 I    +---+-o I   I o I
> +------------------------+  I     +---+        +---+   I-+-I
>                             I                            I
>                             +     +---+                  I
>                             +---> I 2 I <----------------+
>                                   +---+
> 
> The memory location for "1" now is unreferenced, and will be given back to
> you immediately.
[...] 
> Olaf
> 

Steven

-- 
"Philosophy is written in this grand book, The Universe. ... But the book
cannot be understood unless one first learns to comprehend the language...
in which it is written. It is written in the language of mathematics, ...;
without which wanders about in a dark labyrinth."   The Lion of Gaul


  • Prev by Date: Re: Re: recode procedural algorithm to faster functional module
  • Next by Date: Discrete Frequency Distribution
  • Previous by thread: Re: What Happens to Garbage in Mathematica?
  • Next by thread: How do I get Timing results in Out[]//<Message>?