Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Memory leak when unmounting component containing user components #781

Closed
stansm opened this issue Jan 2, 2014 · 6 comments · Fixed by #786
Closed

Memory leak when unmounting component containing user components #781

stansm opened this issue Jan 2, 2014 · 6 comments · Fixed by #786
Assignees

Comments

@stansm
Copy link

stansm commented Jan 2, 2014

When unmounting components like this:

<form>
    <label for="exampleInputID">ID</label>
    <SomeUserDefinedComponent/>
</form>

SomeUserDefinedComponent = {
  render: function() {
    return <input/>;
  }
}

a memory leak happens because ReactMount.getID(node) puts DOM nodes back to nodeCache if they are not there.. just right after they were purged from cache.

To fix the leak there is a need for some read-only getID()..

Here is what's happing when unmounting that example component:

  • label component gets purged from nodeCache
  • when ReactDOMInput component is going to unmount it calls this method:
  componentWillUnmount: function() {
    var rootNode = this.getDOMNode();
    var id = ReactMount.getID(rootNode);
    delete instancesByReactID[id];
  }

which contains this.getDOMNode() which iterates through the children of the Form element calling getID() on each of them.. which puts these elements back into the cache.

So first they were purged and here they are all put back in cache causing a memory leak :(

I'm playing with React just 3rd day so not sure of a way to correctly fix this issue

@vjeux
Copy link
Contributor

vjeux commented Jan 2, 2014

(I took the liberty to edit your comment to add syntax highlighting)

@ghost ghost assigned subtleGradient Jan 2, 2014
@sophiebits
Copy link
Collaborator

I can't reproduce this. With this diff https://gist.github.com/spicyj/747c79473b86bbefae0c applied, I loaded http://127.0.0.1:8000/examples/ballmer-peak/ in the console and checked React.__internals.Mount._nodeCache -- it was empty.

Am I misunderstanding?

@stansm
Copy link
Author

stansm commented Jan 2, 2014

Yes. You've missed one more user defined component in there.. Here you go:

$(function() {
    var TestComponent = React.createClass({
        render: function() {
            return <input/>;
        }
    });

    var TestContainer = React.createClass({
        render: function() {
            return (
                <div>
                <label>label1</label>
                <label>label2</label>
                <TestComponent/>
                </div>
            );
        }
    });

    var el = document.getElementById('somediv');
    React.renderComponent(
        <TestContainer/>,
        el,
        function() {
            React.unmountComponentAtNode(el);
            console.log(React.__internals.Mount._nodeCache);
        }
    );

});

@sophiebits
Copy link
Collaborator

Thanks, fixed in #786.

@stansm
Copy link
Author

stansm commented Jan 3, 2014

Thank you for fast fix :)

@stansm stansm closed this as completed Jan 3, 2014
sophiebits added a commit to sophiebits/react that referenced this issue Jan 9, 2014
zpao added a commit that referenced this issue Jan 9, 2014
Fix potential memory leak when unmounting
@jordwalke
Copy link
Contributor

Thanks for the find/fix!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants