pycall.rb icon indicating copy to clipboard operation
pycall.rb copied to clipboard

Memory leak?

Open mknkmyzk opened this issue 3 years ago • 4 comments

As stated in https://qiita.com/yagshi/items/e3865fae585c348c5bfc (thank you @yagshi), I experience memory leak with the following code:

require "pycall"
cv2 = PyCall.import_module("cv2")
1000 times do
  img = cv2.imread("foo.jpg")
  puts img.shape
end

To cope with this problem, I insert several Py_decrefs in pycall.c. Tentative patch is posted in Pull request.

mknkmyzk avatar Sep 15 '20 10:09 mknkmyzk

Ruby employs mark-and-sweep GC while Python employs reference counting.

In Python, objects are freed when their reference count become zero. So all block-local objects are freed when leaving the block.

In contrast, Ruby's GC runs only when it is necessary. There are two situations GC needs to run in Ruby:

  • The heap slot array should be expanded when a new object will be allocated
  • xmalloc is failed

When you want to run GC explicitly, you can do it by calling GC.start.

Please insert GC.start following puts img.shape and try to run the script. You will see the memory usage is not increased.

mrkn avatar Sep 23 '20 02:09 mrkn

Thank you for your reply. The case of memory leak is not clear for me. As you pointed out, the memory leak can be avoided if I put GC.start after put img.shape. But the following code also shows a memory leak:

require "pycall"
cv2 = PyCall.import_module("cv2")
gc = PyCall.import_module("gc")

10000.times do
  img = cv2.imread("ch00001.jpg") or raise 'Cannot read'
  # puts img.shape
  img.copy()
  GC.start
  gc.collect()
end

In another case, the following code shows a memory leak as well:

require 'pycall'

a = Array.new(100000)

100000.times{
  PyCall.tuple(a)
  GC.start
}

My environment is Fedora32 ruby 2.7.1p83 python 3.8.5

mknkmyzk avatar Sep 23 '20 05:09 mknkmyzk

@mknkmyzk Did you figured out how to solve this issue? 🙇🏻

andreimerfu avatar Dec 09 '21 21:12 andreimerfu

Please check the patch in issue#129 or try my forked version https://github.com/mknkmyzk/pycall.rb

mknkmyzk avatar Dec 13 '21 01:12 mknkmyzk

@mknkmyzk @andreimerfu I'm sorry for being too late. I've released v1.5.0 with #129. The Python objects memory leak should be resolved now. Could you please check with the new version again?

mrkn avatar Aug 25 '23 01:08 mrkn