Re: How to free memory?
- To: mathgroup at smc.vnet.net
- Subject: [mg59798] Re: How to free memory?
- From: "Wonseok Shin" <wssaca at gmail.com>
- Date: Mon, 22 Aug 2005 02:48:15 -0400 (EDT)
- References: <de46jr$r62$1@smc.vnet.net><de6lru$cg5$1@smc.vnet.net> <de9cs2$q5l$1@smc.vnet.net>
- Sender: owner-wri-mathgroup at wolfram.com
Carl K. Woll wrote: > "Wonseok Shin" <wssaca at gmail.com> wrote in message > news:de6lru$cg5$1 at smc.vnet.net... > > Now I want to be more specific. > > > > I've read the "Garbage Collection" thread that has been going on for > > the past few days, and tried all solutions in there. But those > > couldn't resolve my problem. > > > > Here goes my code: > > -------------------------------------------------------------------------- > > In[1]:= > > $HistoryLength = 0; > > > > In[1]:= > > n1=3.5; n2=1.5; d1=0.5; d2=1.0; a = d1 + d2; > > > > In[2]:= > > eig[x_]:= > > Module[{eigVal, eigVec, T1, T2, T, k1=2Pi n1/x, k2 = 2Pi n2/x, A1, > > B1, A2, > > B2, e1, e2, h1, h2,coeff, e, de1, de2, de}, > > > > (* Calculates the matrix. *) > > T1={{Cos[2Pi n1 d1/x], -I Sin[2Pi n1 d1/x] /n1}, {-I Sin[2Pi n1 > > d1/x] n1, Cos[2Pi n1 d1/x]}}; > > T2={{Cos[2Pi n2 d2/x], -I Sin[2Pi n2 d2/x] /n2}, {-I Sin[2Pi n2 > > d2/x] n2, Cos[2Pi n2 d2/x]}}; > > T=T2.T1; > > > > (* Calculates the eigenvalue and eigenvector of T. *) > > eigVal = Eigenvalues[T][[1]]; > > eigVec = Eigenvectors[T][[1]]; > > > > (* Defines the equations for the eigenmodes in 0 = z = a. *) > > e1[z_]:= A1 Exp[I k1 z] + B1 Exp[-I k1 z]; > > e2[z_]:= A2 Exp[I k2 z] + B2 Exp[-I k2 z]; > > h1[z_]:=-n1 (A1 Exp[I k1 z] - B1 Exp[-I k1 z]); > > h2[z_]:=-n2 (A2 Exp[I k2 z] - B2 Exp[-I k2 z]); > > > > (* Determines the coefficients using the boundary conditions *) > > coeff=Solve[{{e1[0], h1[0]} == eigVec, e1[d1]==e2[0], > > h1[d1]==h2[0]}, {A1, B1, A2, B2 }]; > > > > (* Redefines the functions. *) > > DownValues[e1] = DownValues[e1] /. coeff; > > DownValues[e2] = DownValues[e2] /. coeff; > > > > (* Gets the eigenmode. *) > > e[z_ /; 0 = Mod[z, a] < d1] := eigVal^Quotient[z,a] * e1[z - a > ^ > | > > should be <= as well as a few more times below > > > Quotient[z, a]]; > > e[z_ /; d1 = Mod[z, a] < a] := eigVal^Quotient[z,a] * e2[z - (a > > Quotient[z, a] + d1)]; > > > > (* Takes the derivatives of the eigenmode. *) > > de1[z_] = D[e1[z], z]; > > de2[z_] = D[e2[z], z]; > > > > de[z_ /; 0 = Mod[z, a] < d1] := eigVal^Quotient[z, a] * de1[z - a > > Quotient[z, a]]; > > de[z_ /; d1 = Mod[z, a] < a] := eigVal^Quotient[z, a] * de2[z - > > (a Quotient[z, a] + d1)]; > > > > (* Returns the eigenmode and its derivative functions. *) > > {e, de} > > ] > > > > Your function eig returns two new functions e and de (actually e$nnn and > de$nnn). These functions in turn depend on e1,e2,de1,de2,k1,k2 and eigVal. > > > In[3]:= > > eig[0.1][[2]][30] (* Checks if the function eig[x] works well. *) > > > > Out[3]= > > -2.3088026412307006`*^-11 - 56.97491898475945 I > > > > In[4]:= > > MemoryInUse[] > > > > Out[4]= > > 3033832 > > > > In[5]:= > > data = Table[eig[x], {x, 5, 10, 0.001}]; (* Generate a huge list of > > eigenmodes and its derivative pairs *) > > > > You've created ~5000 definitions of e and de, and set data equal to a list > of these functions. > > > In[6]:= > > MemoryInUse[] > > > > Out[6]= > > 52423632 > > > > In[7]:= > > data=.; Clear[data]; Remove[data]; > > > > In[8]:= > > MemoryInUse[] > > > > Out[8]= > > 52425096 > > (* data was not released. *) > > -------------------------------------------------------------------------- > > > > So, why isn't data released here? > > > > Clearing data doesn't clear the function definitions. For example: > > f[x_]:=1 > > data=f; > > Clear[data] > > In[63]:= > f[x] > Out[63]= > 1 > > and we see that f is still defined. If you want to clear all of the new > functions you've created, you need to use Clear on those functions. In your > case we need to do the following: > > Clear["e$*", "de$*", "e1$*", "e2$*", "de1$*", "de2$*", "k1$*", "k2$*", \ > "eigVal$*"] > > Let's see how memory usage works in your case. We start out with a memory in > use of ~7MB: > > In[21]:= > MemoryInUse[] > Out[21]= > 6723448 > > Creating data increases memory used ~55MB: > > In[22]:= > data = Table[eig[x], {x, 5, 10, 0.001}]; //Timing > MemoryInUse[] > Out[22]= > {16.297 Second,Null} > Out[23]= > 55634032 > > Clearing data doesn't do much since function definitions remain: > > In[24]:= > Clear[data] > MemoryInUse[] > Out[25]= > 55453680 > > Clearing function definitions and internal variables helps: > > In[26]:= > Clear["e$*","de$*","e1$*","e2$*","de1$*","de2$*","k1$*","k2$*","eigVal$*"] > MemoryInUse[] > Out[27]= > 18776968 > > The final bit of memory usage is tied up with the cache: > > In[28]:= > Developer`ClearCache[] > MemoryInUse[] > Out[29]= > 6724176 > > And we are almost back to where we started. > > Carl Woll > Wolfram Research Wow! What you are saying is very huge to me. I though that the scope of the variables defined in a Module is just inside the Module. But as you wrote, the variables defined in a Module can be referred to from outside (by referring e$nnn in my case), and they are effectively global variables! This is quite different from the concept of local variables in the ordinary programming languages like C and C++. Then, is there any way to define local variables resembling those of C and C++, which are automatically destroyed outside some blocks like Module, With, or Block? Or, how can I remedy my code, which generates a lot of unwanted (effectively global) variables? I may do Remove or Clear the variables like e1, e2, h1, and so on before returning {e, de}. Since the concept of local variables which are automatically generated inside a block and destroyed outside the block is very useful in C and C++, I'm sure that there is some elegant way to achieve the same thing in Mathematica. Thanks, Wonseok Shin