{"action":"created","issue":{"url":"https://api.github.com/repos/celluloid/celluloid/issues/463","labels_url":"https://api.github.com/repos/celluloid/celluloid/issues/463/labels{/name}","comments_url":"https://api.github.com/repos/celluloid/celluloid/issues/463/comments","events_url":"https://api.github.com/repos/celluloid/celluloid/issues/463/events","html_url":"https://github.com/celluloid/celluloid/issues/463","id":44747073,"number":463,"title":"Celluloid::Future retaining arguments causing them to not get GC'd","user":{"login":"jonhyman","id":832655,"avatar_url":"https://avatars.githubusercontent.com/u/832655?v=3","gravatar_id":"","url":"https://api.github.com/users/jonhyman","html_url":"https://github.com/jonhyman","followers_url":"https://api.github.com/users/jonhyman/followers","following_url":"https://api.github.com/users/jonhyman/following{/other_user}","gists_url":"https://api.github.com/users/jonhyman/gists{/gist_id}","starred_url":"https://api.github.com/users/jonhyman/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jonhyman/subscriptions","organizations_url":"https://api.github.com/users/jonhyman/orgs","repos_url":"https://api.github.com/users/jonhyman/repos","events_url":"https://api.github.com/users/jonhyman/events{/privacy}","received_events_url":"https://api.github.com/users/jonhyman/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/celluloid/celluloid/labels/reproducible","name":"reproducible","color":"eb6420"}],"state":"open","locked":false,"assignee":{"login":"niamster","id":211000,"avatar_url":"https://avatars.githubusercontent.com/u/211000?v=3","gravatar_id":"","url":"https://api.github.com/users/niamster","html_url":"https://github.com/niamster","followers_url":"https://api.github.com/users/niamster/followers","following_url":"https://api.github.com/users/niamster/following{/other_user}","gists_url":"https://api.github.com/users/niamster/gists{/gist_id}","starred_url":"https://api.github.com/users/niamster/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/niamster/subscriptions","organizations_url":"https://api.github.com/users/niamster/orgs","repos_url":"https://api.github.com/users/niamster/repos","events_url":"https://api.github.com/users/niamster/events{/privacy}","received_events_url":"https://api.github.com/users/niamster/received_events","type":"User","site_admin":false},"milestone":{"url":"https://api.github.com/repos/celluloid/celluloid/milestones/7","html_url":"https://github.com/celluloid/celluloid/milestones/0.16.5","labels_url":"https://api.github.com/repos/celluloid/celluloid/milestones/7/labels","id":1042753,"number":7,"title":"0.16.5","description":"","creator":{"login":"digitalextremist","id":21095,"avatar_url":"https://avatars.githubusercontent.com/u/21095?v=3","gravatar_id":"","url":"https://api.github.com/users/digitalextremist","html_url":"https://github.com/digitalextremist","followers_url":"https://api.github.com/users/digitalextremist/followers","following_url":"https://api.github.com/users/digitalextremist/following{/other_user}","gists_url":"https://api.github.com/users/digitalextremist/gists{/gist_id}","starred_url":"https://api.github.com/users/digitalextremist/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/digitalextremist/subscriptions","organizations_url":"https://api.github.com/users/digitalextremist/orgs","repos_url":"https://api.github.com/users/digitalextremist/repos","events_url":"https://api.github.com/users/digitalextremist/events{/privacy}","received_events_url":"https://api.github.com/users/digitalextremist/received_events","type":"User","site_admin":false},"open_issues":4,"closed_issues":3,"state":"open","created_at":"2015-03-28T08:29:24Z","updated_at":"2015-03-28T23:01:30Z","due_on":"2015-04-27T07:00:00Z","closed_at":null},"comments":18,"created_at":"2014-10-02T22:29:17Z","updated_at":"2015-03-28T23:07:29Z","closed_at":null,"body":"I'm not sure if this is a bug with Ruby (I'm on ruby 2.1.2p95 but the same behavior exists on 2.0.0.-p247) or Celluloid, but due to a memory leak with Futures we can't use Celluloid at all for our use case because memory can grow unbounded quickly and uses up all the RAM on the machine. I've tested 0.15.2 and 0.16.0 and it appears on both. Here's a very simple repro:\r\n\r\n```ruby\r\n# Setup\r\nrequire 'celluloid'\r\n\r\ndef Process.rss ; `ps -o rss= -p #{Process.pid}`.chomp.to_i ; end\r\ndef Process.pretty_rss ; Process.rss.to_s.gsub(/(\\d)(?=(\\d{3})+(\\..*)?$)/,'\\1,') + \" kilobytes\" ; end\r\n\r\nclass Foo\r\n  include Celluloid\r\n  def do_something(arg1)\r\n    return true\r\n  end\r\nend\r\n```\r\n\r\nStoring futures in an array, then iterating back over them causes unbounded memory growth:\r\n```ruby\r\nputs(Process.pretty_rss)\r\n20.times do\r\n  f = Foo.new\r\n  futures = []\r\n  100.times { futures << f.future.do_something(\"a\" * 50_000) }\r\n  futures.length.times {|i| futures[i].value }\r\n  f.terminate()\r\n  futures = []\r\n  puts(Process.pretty_rss)\r\nend\r\n\r\n# => 28,384 kilobytes\r\n# => 33,824 kilobytes\r\n# => 39,624 kilobytes\r\n# => 43,396 kilobytes\r\n# => 48,128 kilobytes\r\n# => 53,320 kilobytes\r\n# => 55,900 kilobytes\r\n# => 56,724 kilobytes\r\n# => 59,920 kilobytes\r\n# => 60,844 kilobytes\r\n# => 60,156 kilobytes\r\n# => 64,408 kilobytes\r\n# => 67,520 kilobytes\r\n# => 66,960 kilobytes\r\n# => 70,604 kilobytes\r\n# => 74,948 kilobytes\r\n# => 76,040 kilobytes\r\n# => 75,472 kilobytes\r\n# => 76,280 kilobytes\r\n# => 75,528 kilobytes\r\n# => 79,584 kilobytes\r\n```\r\n\r\nIf you call `.value` on the future when you make it, growth is contained:\r\n\r\n```ruby\r\nputs(Process.pretty_rss)\r\n20.times do\r\n  f = Foo.new\r\n  futures = []\r\n  100.times { futures << f.future.do_something(\"a\" * 50_000).value }\r\n  f.terminate()\r\n  futures = []\r\n  puts(Process.pretty_rss)\r\nend\r\n\r\n# => 80,384 kilobytes\r\n# => 79,728 kilobytes\r\n# => 80,536 kilobytes\r\n# => 79,912 kilobytes\r\n# => 80,720 kilobytes\r\n# => 80,124 kilobytes\r\n# => 80,932 kilobytes\r\n# => 80,308 kilobytes\r\n# => 79,756 kilobytes\r\n# => 80,564 kilobytes\r\n# => 79,940 kilobytes\r\n# => 80,748 kilobytes\r\n# => 80,124 kilobytes\r\n# => 80,932 kilobytes\r\n# => 80,308 kilobytes\r\n# => 79,756 kilobytes\r\n# => 80,492 kilobytes\r\n# => 80,036 kilobytes\r\n# => 80,844 kilobytes\r\n# => 80,220 kilobytes\r\n```\r\n\r\nEdited by @niamster: test case with a proof https://gist.github.com/niamster/7bbc8a0fcde30f122327"},"comment":{"url":"https://api.github.com/repos/celluloid/celluloid/issues/comments/87326703","html_url":"https://github.com/celluloid/celluloid/issues/463#issuecomment-87326703","issue_url":"https://api.github.com/repos/celluloid/celluloid/issues/463","id":87326703,"user":{"login":"digitalextremist","id":21095,"avatar_url":"https://avatars.githubusercontent.com/u/21095?v=3","gravatar_id":"","url":"https://api.github.com/users/digitalextremist","html_url":"https://github.com/digitalextremist","followers_url":"https://api.github.com/users/digitalextremist/followers","following_url":"https://api.github.com/users/digitalextremist/following{/other_user}","gists_url":"https://api.github.com/users/digitalextremist/gists{/gist_id}","starred_url":"https://api.github.com/users/digitalextremist/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/digitalextremist/subscriptions","organizations_url":"https://api.github.com/users/digitalextremist/orgs","repos_url":"https://api.github.com/users/digitalextremist/repos","events_url":"https://api.github.com/users/digitalextremist/events{/privacy}","received_events_url":"https://api.github.com/users/digitalextremist/received_events","type":"User","site_admin":false},"created_at":"2015-03-28T23:07:29Z","updated_at":"2015-03-28T23:07:29Z","body":"@niamster, is there a way for the repro to reflect that, or is this `wontfix/notanissue` because the repro is not in fact hemorrhaging memory any more -- even though it fails to quit?"}}