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