{"action":"created","issue":{"url":"https://api.github.com/repos/gplepage/gvar/issues/3","repository_url":"https://api.github.com/repos/gplepage/gvar","labels_url":"https://api.github.com/repos/gplepage/gvar/issues/3/labels{/name}","comments_url":"https://api.github.com/repos/gplepage/gvar/issues/3/comments","events_url":"https://api.github.com/repos/gplepage/gvar/issues/3/events","html_url":"https://github.com/gplepage/gvar/issues/3","id":315257943,"number":3,"title":"Memory leak ","user":{"login":"r-nepton","id":28274632,"avatar_url":"https://avatars0.githubusercontent.com/u/28274632?v=4","gravatar_id":"","url":"https://api.github.com/users/r-nepton","html_url":"https://github.com/r-nepton","followers_url":"https://api.github.com/users/r-nepton/followers","following_url":"https://api.github.com/users/r-nepton/following{/other_user}","gists_url":"https://api.github.com/users/r-nepton/gists{/gist_id}","starred_url":"https://api.github.com/users/r-nepton/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/r-nepton/subscriptions","organizations_url":"https://api.github.com/users/r-nepton/orgs","repos_url":"https://api.github.com/users/r-nepton/repos","events_url":"https://api.github.com/users/r-nepton/events{/privacy}","received_events_url":"https://api.github.com/users/r-nepton/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":0,"created_at":"2018-04-17T22:02:21Z","updated_at":"2018-04-18T17:12:46Z","closed_at":null,"author_association":"NONE","body":"Aloha, \r\n\r\nI was tracking a memory leak in a code and narrowed down the source of the leak to gvar using the following test loop:\r\n\r\n#!/usr/bin/env python\r\n\r\nimport gvar\r\nimport numpy as np\r\n\r\nfor i in range(4000000):\r\n        spectrum = np.arange(100)\r\n        spectrum = gvar.gvar(spectrum, np.ones(100))\r\n\r\n![screen shot 2018-04-17 at 11 57 12](https://user-images.githubusercontent.com/28274632/38900260-8a0c5dc2-4236-11e8-9f1c-dcb8a72c69e0.jpg)\r\n\r\nIf you could find a fix, it would greatly help!\r\n\r\n4.9.0-5-amd64 #1 SMP Debian 4.9.65-3+deb9u2 (2018-01-04) x86_64 GNU/Linux\r\n\r\nThanks, \r\n\r\nLaurie\r\n"},"comment":{"url":"https://api.github.com/repos/gplepage/gvar/issues/comments/382461101","html_url":"https://github.com/gplepage/gvar/issues/3#issuecomment-382461101","issue_url":"https://api.github.com/repos/gplepage/gvar/issues/3","id":382461101,"user":{"login":"gplepage","id":1808545,"avatar_url":"https://avatars3.githubusercontent.com/u/1808545?v=4","gravatar_id":"","url":"https://api.github.com/users/gplepage","html_url":"https://github.com/gplepage","followers_url":"https://api.github.com/users/gplepage/followers","following_url":"https://api.github.com/users/gplepage/following{/other_user}","gists_url":"https://api.github.com/users/gplepage/gists{/gist_id}","starred_url":"https://api.github.com/users/gplepage/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gplepage/subscriptions","organizations_url":"https://api.github.com/users/gplepage/orgs","repos_url":"https://api.github.com/users/gplepage/repos","events_url":"https://api.github.com/users/gplepage/events{/privacy}","received_events_url":"https://api.github.com/users/gplepage/received_events","type":"User","site_admin":false},"created_at":"2018-04-18T17:12:46Z","updated_at":"2018-04-18T17:12:46Z","author_association":"OWNER","body":"This is not really a leak; the code is doing what it is supposed to do. The `GVar` variables created in your last line are being discarded, but their variances are being retained (in case those variables were used to create other variables). To illustrate what is going on consider the following example:\r\n\r\n    import gvar as gv\r\n    import numpy as np\r\n\r\n    def f():\r\n        x = gv.gvar('1(1)')\r\n        y = gv.gvar('2.0(5)')\r\n        return [x + y, x - y, y * gv.cos(x / y), gv.log(x * y)]\r\n\r\n    z = f()\r\n    print(gv.evalcov(z))\r\n\r\nHere the `GVar` variables `x` and `y` are discarded at the end of `f()`, but their variances are stored (globally) so that the covariances between the different components of `z` can be constructed when needed. The covariance matrix for the `z[i]` is printed by the last line and is:\r\n\r\n    [[ 1.25        0.75       -0.20010171  1.125     ]\r\n     [ 0.75        1.25       -0.75874937  0.875     ]\r\n     [-0.20010171 -0.75874937  0.54193606 -0.33976362]\r\n     [ 1.125       0.875      -0.33976362  1.0625    ]]\r\n\r\nThe variances (or covariances) for any new `GVar`(s) created using `gvar.gvar(...)` are automatically retained for this purpose. The `gvar` module would be a lot simpler if it wasn't required to capture the correlations between the different `z[i]`s.\r\n\r\nThis behavior doesn't seem to make sense for your example where you create 40 billion `GVar`s that you never use, but I assume that your real code actually does use these variables. If it is the case that the `GVar`s used in one iteration are of no relevance to any other iteration of the loop, then it is possible to avoid the memory build up by using a different version of the function `gvar.gvar` in each iteration:\r\n\r\n    import gvar as gv\r\n    import numpy as np\r\n\r\n    for i in range(4000000):\r\n        tmp_gvar = gv.gvar_factory()\r\n        spectrum = np.arange(100)\r\n        spectrum = tmp_gvar(spectrum, np.ones(100))\r\n\r\nThis hasn't been useful for the things I do, but it might be relevant for other work.\r\n"}}
{"actor":{"display_login":"gplepage"}}