16

I know that python has an automatic garbage collector and so it should automatically delete variables when there are no more reference to them.

My impression is that this does not happen for local variables (inside a function).

def funz(z):
    x = f(z) # x is a np.array and contains a lot of data
    x0 = x[0]
    y = f(z + 1) # y is a np.array and contains a lot of data
    y0 = y[0]

    # is x and y still available here?
    return y0, x0

Is del x the right way to save memory?

def funz(z):
    x = f(z) # x is a np.array and contains a lot of data
    x0 = x[0]
    del x
    y = f(z + 1) # y is a np.array and contains a lot of data
    y0 = y[0]
    del y

    return y0, x0

EDIT: I have edited my example such that it is more similar to my real problem. In my real problem x and y are not lists but classes that contain different large np.array.

EDIT: I am able to run the code:

x = f(z)
x0 = x[0]
print(x0)

y = f(z + 1)
y0 = [0]
print(y0)
Girrafish
  • 2,320
  • 1
  • 19
  • 32
Donbeo
  • 17,067
  • 37
  • 114
  • 188
  • 3
    *My impression is that this does not happen for local variables (inside a function).* What gave you that impression? Local names are cleaned up when the function ends; the objects they referenced are deleted when their reference count drops to 0 *just like anywhere else in Python*. – Martijn Pieters Aug 13 '14 at 12:29
  • I have a function that run consequently some independent scripts. I receive an out of memory error. I know that I was able to run these scripts independently – Donbeo Aug 13 '14 at 12:30
  • @Donbeo: when the function runs the scripts, how are you running them? Are they running as separate processes or as modules? – cdarke Aug 13 '14 at 13:02
  • @MartijnPieters the OP may be confused by the fact that 'scope' in python is different from 'scope' in many other languages. For example a ``for`` loop does not define a new scope and its variables will still be alive after the final iteration. – aruisdante Aug 13 '14 at 13:04

4 Answers4

16

Implementations use reference counting to determine when a variable should be deleted.

After the variable goes out of scope (as in your example) if there are no remaining references to it, then the memory will be freed.

def a():
    x = 5 # x is within scope while the function is being executed
    print x

a()
# x is now out of scope, has no references and can now be deleted

Aside from dictionary keys and elements in lists, there's usually very little reason to manually delete variables in Python.

Though, as said in the answers to this question, using del can be useful to show intent.

Community
  • 1
  • 1
flau
  • 1,328
  • 1
  • 20
  • 36
  • 3
    An important note: garbage collecting and reference counting are *not* the same thing, and Python does both. Garbage collection is however mostly used to clean up circular references and is thus not the primary form of memory management. Reference counting frees memory as soon as the reference count drops to zero, it doesn't wait for a GC cycle. There are of course some exceptions as python will cache integers and short strings even if there are no live references to them for performance reasons. – aruisdante Aug 13 '14 at 13:08
7

It's important to keep two concepts separate: names and values. A variable in Python is a name referring to a value. Names have scope: when you define a local variable (by assigning a value to a name), the variable's scope is the current function. When the function returns, the variable goes away. But that doesn't mean the value goes away.

Values have no scope: they stick around until there are no more names referring to them. You can create a value in a function, and return it from that function, making a name outside the function refer to the value, and the value won't be reclaimed until some future point when all the references to it have gone away.

More detail (including pictures!) is here: Facts and Myths about Python Names and Values.

Ned Batchelder
  • 364,293
  • 75
  • 561
  • 662
0

Write stuff you want to clear from memory in separate functions. In your example, you can do

  def xdef(z):
    x = f(z) # x is a np.array and contains a lot of data 
    x0 = x[0]

  def funz(z):
    xdef(z)
    y = f(z + 1) # y is a np.array and contains a lot of data
    y0 = y[0]  

    return y[0], x[0] 

This will cause an exception

0

It depends on the implementation and the type of variable. For simple objects like ints there are some optimisations. In CPython, for example, a simple int will reuse the same memory, even after del has been used. You can't count on that, but it does illustrate that things are more complex than they appear.

Remember that when you del you are deleting a name, not necessarily an object.
For example:

# x is a np.array and contains a lot of data

Would be more accurately worded as:

# x references a np.array which contains a lot of data

del will decrement the reference count on that object, but even when it drops to zero it is not guaranteed to be garbage collected any time soon.

Suggest you look at the gc module for an explanation and inspiration. Then think again.

If you are getting "out of memory" then you probably have a fundamental problem with your design. Most likely you are loading too much data in at one go (try using iterators?), or maybe your code need to be structured better.

I just saw your edit. Do you need all of that array in memory at the same time? Could you use a generator?

Another alternative is to use a database like SQLite or maybe a shelve

cdarke
  • 42,728
  • 8
  • 80
  • 84
  • yes I need all the list. this example is not exactly what I have in my code. In my code f returns a class where some of the elements in this class are large np.ndarray. If I can delete manually variables with something like del then I think that my problem would be solved – Donbeo Aug 13 '14 at 12:54