This Bugzilla instance is deprecated, and most Eclipse projects now use GitHub or Eclipse GitLab. Please see the deprecation plan for details.
Bug 389251 - [Performance] Idle Eclipse constantly allocates hundreds of objects per second
Summary: [Performance] Idle Eclipse constantly allocates hundreds of objects per second
Status: VERIFIED FIXED
Alias: None
Product: Platform
Classification: Eclipse Project
Component: UI (show other bugs)
Version: 4.1   Edit
Hardware: PC Windows 7
: P3 major with 1 vote (vote)
Target Milestone: 4.2.2   Edit
Assignee: Paul Elder CLA
QA Contact:
URL:
Whiteboard:
Keywords: performance
Depends on:
Blocks: 385272
  Show dependency tree
 
Reported: 2012-09-11 09:08 EDT by Dani Megert CLA
Modified: 2013-01-17 11:02 EST (History)
13 users (show)

See Also:


Attachments
Screen captures for comment on Bug 389251 (312.19 KB, application/octet-stream)
2012-11-04 12:59 EST, R Kay CLA
no flags Details
Patch (705 bytes, patch)
2012-12-20 12:08 EST, Szymon Ptaszkiewicz CLA
no flags Details | Diff
A patch (2.28 KB, patch)
2012-12-21 14:08 EST, Snjezana Peco CLA
no flags Details | Diff
A patch (2.28 KB, patch)
2012-12-21 15:57 EST, Snjezana Peco CLA
no flags Details | Diff
A patch (1.09 KB, patch)
2012-12-21 16:50 EST, Snjezana Peco CLA
no flags Details | Diff
Avoid isTouch events associated with menu/toolbar enablement + reduce object creation during message dispatch (3.05 KB, patch)
2013-01-15 10:39 EST, Paul Elder CLA
no flags Details | Diff
A patch (1.45 KB, patch)
2013-01-17 09:05 EST, Snjezana Peco CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Dani Megert CLA 2012-09-11 09:08:31 EDT
M20120909-2000.

The idle Eclipse constantly allocates hundreds of objects (mostly char[], int[], String and others) per second even though the IDE is idle.

Test Case:
1. start a new workspace
2. close the Welcome page
3. wait until all is idle
4. start to profile the memory
===> see never ending allocation of hundred of objects per second (and then GCed later).
Comment 1 Dani Megert CLA 2012-09-11 09:10:42 EDT
The top rows of attachment 220933 [details] give a hint.
Comment 2 John Arthorne CLA 2012-09-11 10:35:09 EDT

*** This bug has been marked as a duplicate of bug 385394 ***
Comment 3 Dani Megert CLA 2012-09-11 10:51:21 EDT
(In reply to comment #2)
> 
> *** This bug has been marked as a duplicate of bug 385394 ***

John, did you *verify* that those objects are coming from the timer thread?
Comment 4 Dani Megert CLA 2012-09-12 08:52:33 EDT
(In reply to comment #3)
> (In reply to comment #2)
> > 
> > *** This bug has been marked as a duplicate of bug 385394 ***
> 
> John, did you *verify* that those objects are coming from the timer thread?

I did not track down each case but to test I simply removed the code/problem mentioned in bug 385394 and that does not remove all the allocations while idle. Below is just one stack showing repeated allocations of ContextChangeEvent. This does not happen every 400ms but about all 5s:

Thread [main] (Suspended (breakpoint at line 92 in ContextChangeEvent))	
	ContextChangeEvent.<init>(IEclipseContext, int, Object[], String, Object) line: 92	
	EclipseContextOSGi(EclipseContext).processWaiting() line: 514	
	EclipseContext.processWaiting() line: 506	
	PartRenderingEngine$9.run() line: 1031	
	Realm.runWithDefault(Realm, Runnable) line: 332	
	PartRenderingEngine.run(MApplicationElement, IEclipseContext) line: 924	
	E4Workbench.createAndRunUI(MApplicationElement) line: 86	
	Workbench$5.run() line: 588	
	Realm.runWithDefault(Realm, Runnable) line: 332	
	Workbench.createAndRunWorkbench(Display, WorkbenchAdvisor) line: 543	
	PlatformUI.createAndRunWorkbench(Display, WorkbenchAdvisor) line: 149	
	IDEApplication.start(IApplicationContext) line: 124	
	EclipseAppHandle.run(Object) line: 196	
	EclipseAppLauncher.runApplication(Object) line: 110	
	EclipseAppLauncher.start(Object) line: 79	
	EclipseStarter.run(Object) line: 353	
	EclipseStarter.run(String[], Runnable) line: 180	
	NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not available [native method]	
	NativeMethodAccessorImpl.invoke(Object, Object[]) line: 39	
	DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 25	
	Method.invoke(Object, Object...) line: 597	
	Main.invokeFramework(String[], URL[]) line: 629	
	Main.basicRun(String[]) line: 584	
	Main.run(String[]) line: 1438	
	Main.main(String[]) line: 1414
Comment 5 Dani Megert CLA 2012-09-12 10:05:32 EDT
(In reply to comment #4)
> Below is just one stack showing repeated allocations of
> ContextChangeEvent. This does not happen every 400ms but about all 5s:
> 

This (and other instances, e.g. strings) are created by
org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(MApplicationElement, IEclipseContext) which runs around 16 time per second!
Comment 6 R Kay CLA 2012-11-04 12:58:00 EST
I was about to write up essentially the same bug report when Bugzilla found this one for me.

I had earlier reported similar behavior here => http://www.eclipse.org/forums/index.php/m/900216/?srch=memory#msg_900216

I use Eclipse on WinXP and Win7 with Java 1.6.014 and 1.6.035. Ever since I installed Eclipse 4.2 IDE for Java, I have watched my memory grow and contract incessantly. I use Eclipse with the EPIC and Statet plugins but the problem exists even on a clean install without any plugins. The issue for me is that if I run a R language script right before the GC does a collection, then there is not enough memory available and more memory needs to be allocated. As a result, I can see my Eclipse heap growing all day without any real reason.

With Eclipse 4.2.1 at least one of the bugs (386070) was fixed but it seems like there is at least 1 more bug that needs attention.

I see that this report may have been marked a duplicate and then reopened. The purpose of my comment is to reinforce that this is not a trivial problem for users since it does affect performance.

I have attached a bunch of screen captures of what I can see by profiling Eclipse-SDK with VisualVM. The magnitude of the problem is worse with Eclipse IDE for Java which is what I use regularly.

Thanks for the hard work in making Eclipse a great IDE.
RKay
Comment 7 R Kay CLA 2012-11-04 12:59:58 EST
Created attachment 223153 [details]
Screen captures for comment on Bug 389251

This zip archive may be useful to figure out if I am seeing the same bug as the OP. It certainly seems that way to me.
Comment 8 Szymon Ptaszkiewicz CLA 2012-12-20 11:47:56 EST
(In reply to comment #5)
> (In reply to comment #4)
> > Below is just one stack showing repeated allocations of
> > ContextChangeEvent. This does not happen every 400ms but about all 5s:
> > 
> 
> This (and other instances, e.g. strings) are created by
> org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.
> run(MApplicationElement, IEclipseContext) which runs around 16 time per
> second!

I can reproduce it on I20121214-0730. This case can be easily solved by a simple fix. Patch will follow.
Comment 9 Szymon Ptaszkiewicz CLA 2012-12-20 12:08:34 EST
Created attachment 224965 [details]
Patch
Comment 10 Paul Webster CLA 2012-12-20 13:11:27 EST
(In reply to comment #9)
> Created attachment 224965 [details]
> Patch

Do you want this released?

PW
Comment 11 Szymon Ptaszkiewicz CLA 2012-12-20 14:01:35 EST
(In reply to comment #10)
> (In reply to comment #9)
> > Created attachment 224965 [details]
> > Patch
> 
> Do you want this released?
> 
> PW

Yes, if the patch is ok and there are no objections, then please release it (unfortunately, I can't do that myself yet ;-).
Comment 13 Paul Webster CLA 2012-12-20 14:59:03 EST
While looking at Szymon's patch, I discovered org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.someAreVisible(List<MWindow>)

It creates an iterator to check for visible windows in the application on every pass through the display loop.

An optimization would be to use a boolean for the event loop, and use an EventHandler to listen for visible or toBeRendered changes on the MApplication child windows. to keep it up to date.

Paul, when you get a chance could you look at this?

PW
Comment 14 Snjezana Peco CLA 2012-12-21 14:07:05 EST
If there is some toolbar contribution ("Select Maven Profiles" from JBoss Tools or "GDT Pulldown" from the Google Suite plugin, for instance), Eclipse often calls the HandledContributionItem.updateItemEnablement method that calls the EclipseContext.invalidate() method that unnecessarily creates a lot of the ContextChangeEvent objects.

Attached is a patch. It includes Szymon's patch that isn't applied to the master yet.
Comment 15 Snjezana Peco CLA 2012-12-21 14:08:32 EST
Created attachment 225002 [details]
A patch
Comment 16 Paul Webster CLA 2012-12-21 14:25:58 EST
(In reply to comment #15)
> Created attachment 225002 [details]
> A patch

Released to http://git.eclipse.org/c/platform/eclipse.platform.runtime.git/commit/?h=R4_2_maintenance&id=6f90c7b6b3ca496b29382c792c4192eb27b3d882

I'll merge them both into master today.

PW
Comment 17 Nobody - feel free to take it CLA 2012-12-21 14:27:11 EST
I just wanted to add that in most profilings I made using the JVisualVM almost always the most called method in an idle state was EclipseContext.invalidate();
Comment 18 Snjezana Peco CLA 2012-12-21 15:56:16 EST
The ItemImpl.setEnabled method (org.eclipse.e4.ui.model.workbench) creates the ENotificationImpl object even if the value of the 'enabled' variable isn't changed.
The method is often called if there is some toolbar contribution (comment #14)

Attached is a patch.
Comment 19 Snjezana Peco CLA 2012-12-21 15:57:39 EST
Created attachment 225007 [details]
A patch
Comment 20 Robert Munteanu CLA 2012-12-21 16:14:32 EST
(In reply to comment #19)
> Created attachment 225007 [details]
> A patch

I think you uploaded the original patch again.
Comment 21 Snjezana Peco CLA 2012-12-21 16:50:42 EST
Created attachment 225008 [details]
A patch
Comment 22 Paul Webster CLA 2012-12-24 09:33:10 EST
(In reply to comment #21)
> Created attachment 225008 [details]
> A patch

We expect org.eclipse.emf.common.notify.Notification.isTouch() to return true if something sets the same value.  Won't your patch prevent that?

PW
Comment 23 Snjezana Peco CLA 2012-12-24 13:24:14 EST
(In reply to comment #22)
> 
> We expect org.eclipse.emf.common.notify.Notification.isTouch() to return
> true if something sets the same value.  Won't your patch prevent that?
> 

The patch prevents Notification.isTouch(), but ItemImpl.notifyChanged() ignores that.
See UIEventPublisher.notifyChanged
BTW, we could call ToolItemUpdateTimer.run() using a part listener and a bundle listener instead of Display.timerExec. This would significantly improve performance.
I could try to create a patch if you agree.
Comment 24 Paul Webster CLA 2012-12-24 13:37:36 EST
(In reply to comment #23)
 The patch prevents Notification.isTouch(), but ItemImpl.notifyChanged()
> ignores that.
> See UIEventPublisher.notifyChanged
> BTW, we could call ToolItemUpdateTimer.run() using a part listener and a
> bundle listener instead of Display.timerExec. This would significantly
> improve performance.
> I could try to create a patch if you agree.

We're looking at removing the timerExec in bug 385394

PW
Comment 25 Paul Elder CLA 2013-01-15 10:39:31 EST
Created attachment 225637 [details]
Avoid isTouch events associated with menu/toolbar enablement + reduce object creation during message dispatch

Patch does two things:
* Change to HandledContributionItem prevents the 'storm' of EventNotifications that Snjezana noted and tried to patch, but without touching the EMF-generated code.
* Change to PartRenderingEngine eliminates the creation (and ultimate GC-ing) of an Iterator instance every time through the message dispatch loop.

With this changes in place, the workbench Heap Status no longer creeps up while the workbench is idle.
Comment 26 Paul Webster CLA 2013-01-15 13:09:30 EST
(In reply to comment #25)
> Created attachment 225637 [details]
> Avoid isTouch events associated with menu/toolbar enablement + reduce object
> creation during message dispatch

Released as http://git.eclipse.org/c/platform/eclipse.platform.ui.git/commit/?h=R4_2_maintenance&id=9a9ea5bd37a298580637db43d7c29502923ecdda

Please open a new bug for any new allocation churn that's not already covered by the timerExec bug.

Thank you everybody.

PW
Comment 27 Snjezana Peco CLA 2013-01-17 09:05:43 EST
Created attachment 225766 [details]
A patch

I have attached a small patch that prevents unnecessarily creating an array of Runnable.
Comment 28 Lars Vogel CLA 2013-01-17 09:19:12 EST
@Snjezana I think Paul suggested to open new bugs for new improvements.
Comment 29 Snjezana Peco CLA 2013-01-17 09:31:48 EST
(In reply to comment #28)
> @Snjezana I think Paul suggested to open new bugs for new improvements.

I have created https://bugs.eclipse.org/bugs/show_bug.cgi?id=398399 .
Comment 30 Paul Webster CLA 2013-01-17 11:02:13 EST
in M20130116-1800
PW