{"action":"created","issue":{"url":"https://api.github.com/repos/robovm/robovm/issues/749","labels_url":"https://api.github.com/repos/robovm/robovm/issues/749/labels{/name}","comments_url":"https://api.github.com/repos/robovm/robovm/issues/749/comments","events_url":"https://api.github.com/repos/robovm/robovm/issues/749/events","html_url":"https://github.com/robovm/robovm/issues/749","id":56947185,"number":749,"title":"Memory leak with view controllers creation/removal","user":{"login":"mirkonasato","id":133967,"avatar_url":"https://avatars.githubusercontent.com/u/133967?v=3","gravatar_id":"","url":"https://api.github.com/users/mirkonasato","html_url":"https://github.com/mirkonasato","followers_url":"https://api.github.com/users/mirkonasato/followers","following_url":"https://api.github.com/users/mirkonasato/following{/other_user}","gists_url":"https://api.github.com/users/mirkonasato/gists{/gist_id}","starred_url":"https://api.github.com/users/mirkonasato/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mirkonasato/subscriptions","organizations_url":"https://api.github.com/users/mirkonasato/orgs","repos_url":"https://api.github.com/users/mirkonasato/repos","events_url":"https://api.github.com/users/mirkonasato/events{/privacy}","received_events_url":"https://api.github.com/users/mirkonasato/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/robovm/robovm/labels/bug","name":"bug","color":"fc2929"},{"url":"https://api.github.com/repos/robovm/robovm/labels/high","name":"high","color":"009800"}],"state":"open","locked":false,"assignee":{"login":"badlogic","id":514052,"avatar_url":"https://avatars.githubusercontent.com/u/514052?v=3","gravatar_id":"","url":"https://api.github.com/users/badlogic","html_url":"https://github.com/badlogic","followers_url":"https://api.github.com/users/badlogic/followers","following_url":"https://api.github.com/users/badlogic/following{/other_user}","gists_url":"https://api.github.com/users/badlogic/gists{/gist_id}","starred_url":"https://api.github.com/users/badlogic/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/badlogic/subscriptions","organizations_url":"https://api.github.com/users/badlogic/orgs","repos_url":"https://api.github.com/users/badlogic/repos","events_url":"https://api.github.com/users/badlogic/events{/privacy}","received_events_url":"https://api.github.com/users/badlogic/received_events","type":"User","site_admin":false},"milestone":{"url":"https://api.github.com/repos/robovm/robovm/milestones/5","html_url":"https://github.com/robovm/robovm/milestones/1.0","labels_url":"https://api.github.com/repos/robovm/robovm/milestones/5/labels","id":912076,"number":5,"title":"1.0","description":"","creator":{"login":"ntherning","id":135765,"avatar_url":"https://avatars.githubusercontent.com/u/135765?v=3","gravatar_id":"","url":"https://api.github.com/users/ntherning","html_url":"https://github.com/ntherning","followers_url":"https://api.github.com/users/ntherning/followers","following_url":"https://api.github.com/users/ntherning/following{/other_user}","gists_url":"https://api.github.com/users/ntherning/gists{/gist_id}","starred_url":"https://api.github.com/users/ntherning/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ntherning/subscriptions","organizations_url":"https://api.github.com/users/ntherning/orgs","repos_url":"https://api.github.com/users/ntherning/repos","events_url":"https://api.github.com/users/ntherning/events{/privacy}","received_events_url":"https://api.github.com/users/ntherning/received_events","type":"User","site_admin":false},"open_issues":2,"closed_issues":99,"state":"open","created_at":"2014-12-22T10:16:06Z","updated_at":"2015-03-06T16:55:14Z","due_on":"2015-03-09T23:00:00Z","closed_at":null},"comments":18,"created_at":"2015-02-08T10:43:13Z","updated_at":"2015-03-07T15:51:42Z","closed_at":null,"body":"Given a simple app with a navigation controller repeatedly pushing and popping a view controller, the Swift version shows the following memory usage with the Allocations instrument\r\n\r\n![swiftleaker-allocations](https://cloud.githubusercontent.com/assets/133967/6096239/b36cde88-af7e-11e4-874f-800c6724b7f9.png)\r\n\r\nwhile the RoboVM version shows a constantly increasing memory usage\r\n\r\n![roboleaker-allocations](https://cloud.githubusercontent.com/assets/133967/6096241/d04792fa-af7e-11e4-8f98-9d176562b62f.png)\r\n\r\nCode available at https://github.com/mirkonasato/robovm-issue-749 - graphs created by clicking ~30 times on the Start then Close buttons at ~1 second intervals.\r\n\r\nThis is with 1.0.0-beta-03."},"comment":{"url":"https://api.github.com/repos/robovm/robovm/issues/comments/77694780","html_url":"https://github.com/robovm/robovm/issues/749#issuecomment-77694780","issue_url":"https://api.github.com/repos/robovm/robovm/issues/749","id":77694780,"user":{"login":"badlogic","id":514052,"avatar_url":"https://avatars.githubusercontent.com/u/514052?v=3","gravatar_id":"","url":"https://api.github.com/users/badlogic","html_url":"https://github.com/badlogic","followers_url":"https://api.github.com/users/badlogic/followers","following_url":"https://api.github.com/users/badlogic/following{/other_user}","gists_url":"https://api.github.com/users/badlogic/gists{/gist_id}","starred_url":"https://api.github.com/users/badlogic/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/badlogic/subscriptions","organizations_url":"https://api.github.com/users/badlogic/orgs","repos_url":"https://api.github.com/users/badlogic/repos","events_url":"https://api.github.com/users/badlogic/events{/privacy}","received_events_url":"https://api.github.com/users/badlogic/received_events","type":"User","site_admin":false},"created_at":"2015-03-07T15:51:42Z","updated_at":"2015-03-07T15:51:42Z","body":"Given this `UIViewController`:\r\n```java\r\npublic class OtherViewController extends UIViewController {\r\n\t@Override\r\n\tpublic void viewDidLoad() {\r\n\t\tsuper.viewDidLoad();\r\n\t\tUIButton closeButton = UIButton.create(UIButtonType.System);\r\n\t\tcloseButton.setFrame(new CGRect(115.0f, 121.0f, 91.0f, 37.0f));\r\n\t\tcloseButton.setTitle(\"Close\", UIControlState.Normal);\r\n\t\tcloseButton.addOnTouchUpInsideListener((control, event) -> {\r\n\t\t\tgetNavigationController().popViewController(false);\r\n\t\t});\r\n\t\tgetView().addSubview(closeButton);\r\n\t}\r\n}\r\n```\r\n\r\nLet's assume that we pushed the controller to a navigation controller, and the controller went out of scope. We end up with this object graph:\r\n\r\n![https://s3.amazonaws.com/pushbullet-uploads/ujEbQh7xysS-PaQBCYlDl5pfMlLfjFl1oMQiRVsFotDD/IMG_20150307_164437.jpg](https://s3.amazonaws.com/pushbullet-uploads/ujEbQh7xysS-PaQBCYlDl5pfMlLfjFl1oMQiRVsFotDD/IMG_20150307_164437.jpg)\r\n\r\nThe view controller has a retain count of 2 at that point, 1 for being referenced by the navigation controller, and one from the Java-side instantiation.\r\n\r\nIf we now pop the view controller, it's retain count becomes 1 and it is removed from `CUSTOM_OBJECTS`. However, it's still reachable via the lambda/Listener, which is referenced by the `ListenerWrapper`, which is referenced by both `CUSTOM_OBJECTS`as well as `ASSOCIATED_OBJECTS`.\r\n\r\nThe GC will never collect the view controller because of this, so all native and Java side objects stay alive.\r\n\r\nIf you manually remove the listener from the UIButton as outlined in my last comment, the cycle between lambda and view controller is broken, and the GC can collect all the things and release the native peers."}}