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

State Registration Memory Consumption #2883

Closed
dneri-accesso opened this issue Jul 20, 2016 · 9 comments
Closed

State Registration Memory Consumption #2883

dneri-accesso opened this issue Jul 20, 2016 · 9 comments
Labels

Comments

@dneri-accesso
Copy link

dneri-accesso commented Jul 20, 2016

When working with many state definitions (1000+) we're noticing huge memory consumption caused by UI Router.

For example, modifying stateSpec.js to include an additional 10000 simple states causes the memory to balloon considerably. This is a problem for larger applications that have very large test suites.

$stateProvider.state('root.sub2', {url: '/2?param2' });

for( var i = 0; i < 10000; i ++) {
  $stateProvider.state('iState' + i, {url: '/Statei' + i});
}

$provide.value('AppInjectable', AppInjectable);

Memory consumed continues to climb past 3 GB

image

Could someone help me understand why UI Router is allocating so much memory?

Tested against:
Node 4.4.7 & Node 5.10.0
Karma 0.12.37
UI Router 0.3.1 (haven't been able to build the master branch successfully, perhaps someone can test there)

Possibly related to #545

@christopherthielen
Copy link
Contributor

(haven't been able to build the master branch successfully, perhaps someone can test there)

run ./scripts/package.sh ng1 and find the package built in ./build_packages/ng1/

@d-neri
Copy link

d-neri commented Jul 23, 2016

Thanks @christopherthielen, the problem seems worse in the master branch.

I had to reduce the sample size to 1000 states instead of 10000. With the latter, the test suite would simply crash after a second or two and disconnect. With 1000, memory continues to grow into the several GBs.

Any thoughts as to why this is happening?

@christopherthielen
Copy link
Contributor

No I'm not sure why registering a state would take up so much memory. I'll try to look into it when I have some time.

Have you tried finding what's taking the memory using dev tools profiler, etc?

@marcoblos
Copy link

+1

@jkevinburton
Copy link

@christopherthielen any progress on this, we are finding the same issues

@christopherthielen
Copy link
Contributor

For example, modifying stateSpec.js to include an additional 10000 simple states causes the memory to balloon considerably.

@danielneri @jkevinburton Are you finding this bloat in production apps, or only during unit testing?

Each run of a unit tests, creates a new angular execution context and a new ui-router instance. The router, all registered states (and likely all of angular) are probably being retained in some way by karma.

Running a simple test in the browser shows that each state takes up about 5k, which is a reasonable amount: http://plnkr.co/edit/LqZ6OwzXXJaGg42XLeyn?p=preview

I started a profiler, clicked "add 1000 states" a few times. Each purple vertical line represents memory allocation of 1000 states, which is a bit over 5MB:
screen shot 2017-03-21 at 5 23 19 pm

By selecting a section of the timeline, we can isolate the memory allocation of a batch of 1000 states. Each state takes up about 5,000 bytes:

screen shot 2017-03-21 at 5 24 25 pm

@fpoljak
Copy link

fpoljak commented Mar 5, 2018

I have a same issue. @danielneri-accesso have you found some workaround for this in unit tests?

@fpoljak
Copy link

fpoljak commented Mar 8, 2018

It seems that router leaks memory because lot of their classes keep reference to each other and it never gets cleaned, probably some circular references get created. This seems to help A LOT:

var clearAllMembers = function(obj, depth) {
	depth = depth || 0;
	if (depth > 10) { // prevent infinite recursion because of circular references
		return;
	}
	for (var i in obj) {
		if (obj.hasOwnProperty(i)) {
			if (typeof(obj[i]) == 'object') {
				clearAllMembers(obj[i], ++depth);
			}
			if (obj) {
				if (obj[i] && (obj[i] instanceof Array) && obj[i].length) {
					obj[i].splice(0);
				}
				delete obj[i];
			}
		}
	}
}

$rootScope.$on('$destroy', function() {
	setTimeout(function() {
		clearAllMembers($stateRegistry);
		clearAllMembers($urlRouter);
		clearAllMembers($urlService);
		clearAllMembers($state);
	});
});

@stale
Copy link

stale bot commented Jan 24, 2020

This issue has been automatically marked as stale because it has not had
recent activity. It will be closed if no further activity occurs.

This does not mean that the issue is invalid. Valid issues
may be reopened.

Thank you for your contributions.

@stale stale bot added the stale label Jan 24, 2020
@stale stale bot closed this as completed Feb 7, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

6 participants