2
votes

I'm new to Lua and I have question regarding to memory management in Lua.

Question 1) When calling function using io.popen(), I saw many Lua programmers wrote a close statement after using popen() function. I wonder what is the reason for that? For example, to demonstrate look at this code:

handle = io.popen("ls -a")
output = handle:read("*all")
handle:close()
print(output)

handle = io.popen("date")
output = handle:read("*all")
handle:close()
print(output)

I heard Lua can manage memory itself. So do I really need to write handle:close like above? What will happen to memory if I just ignore the handle:close() statement and just write it like this?

handle = io.popen("ls -a")
handle = io.popen("date")
output = handle:read("*all")

Question 2) From the code in question 1, in term of memory usage, can we write the handle:close() statement at the end with only one line instead of two like this ?:

handle = io.popen("ls -a")
output = handle:read("*all")
-- handle:close() -- dont close it yet do at the end
print(output)
handle = io.popen("date") -- this use the same variable `handle` previously
output = handle:read("*all")
handle:close()  -- only one statement to close all above
print(output)

You can see that I didn't close this from the first statement when I use io.popen but I close it at the end, will this make the program slow because I close it only with one close statement at the end?

2
file:close() is not about memory management. You should close an opened file handle as fast as possible because it is a very limited OS resource. You can't have a lot of opened files simultaneously. - Egor Skriptunoff
Do you mean io.popen is a file handler method ? I mean io.popen not io.open - Kalib Zen
io.popen creates a pipe and gives you a handle to that pipe. This is a file-like handle. - Egor Skriptunoff
Lua does close file handlers automatically in the nearest GC cycle, but it is deferred unpredictably. It might happen hours after the value become unused. - Egor Skriptunoff
You still have to close the handle. In your 2nd example you're simply reassigning a variable with a new handle, making your old handle unaccessible. The GC may clear the reference memory wise, but the OS won't be able to know that until the process finishes ... - Felix

2 Answers

3
votes

Lua will close the file handle automatically when the garbage collector gets around to collecting it.

Lua Manual 5.4: file:close

Closes file. Note that files are automatically closed when their handles are garbage collected, but that takes an unpredictable amount of time to happen.

BUT, it is best practice to close the handles yourself as soon as you are done with the handle, this is because it will take an unknown amount of time for the GC to do it.

This is not an issue of memory but of a much more limited resource of open file handles, something like 512 on a windows machine, a small pool for all the applications running on it.


As for the second question, when you reassign a variable AND there are no other remaining references to the previous value, that value will eventually be collected by the GC.

2
votes

Question 1

In this case the close is not for memory reasons, but to close the file. When a file handle gets collected, it will be closed automatically, but if a program doesn't generate much garbage (which some programmers specifically optimize for), the GC might not run for quite a while after the program is done with the file handling and the file would stay open.

Also, if the variable stays in scope, then the GC won't get to collect it at all until the scope ends, which might be a very long time.

Question 2

That wouldn't work. Methods get called on values, not on variables, so when you assign a new value to a variable, the old one just disappears. Calling a method on the new value won't affect any other value that used to be stored in the variable.