Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » Standard Widget Toolkit (SWT) » Runnable, RunnableLock instances accumulating on asyncExec(frequent gui updates cause memory leak)
Runnable, RunnableLock instances accumulating on asyncExec [message #1731265] Wed, 04 May 2016 03:07 Go to next message
Andy Junius is currently offline Andy JuniusFriend
Messages: 8
Registered: February 2014
Junior Member
I'm still trying to get into SWT, so maybe that's a beginner question:

I'm working on a time domain plot using Canvas. I implemented this component using JavaFX, Swing and SWT because we have performance issues with JavaFX.

The data gets updated faster than the canvas is able to repaint. So, in Swing I do the following:
    // ...
    SwingUtilities.invokeLater(() -> updateView(data));

void updateView(GraphData data) {
    this.currentGraphData = data;
    this.repaint();
}

This works nicely and it's also performant enough.

A similar approach for my SWT component:
    // ...
    this.getDisplay().asyncExec(() -> updateView(data));

void updateView(GraphData data) {
    if (!this.isDisposed()) {
        this.currentGraphData = data;
        this.redraw(); 
    }
}

This works also nicely, although it seems to be a bit less performant. However it looks like I had a memory leak, because heap space increases over time. This is caused by org.eclipse.swt.widgets.RunnableLock and the Runnable itself accumulating. I'll get a constant heap consumption when I use syncExec instead of asyncExec, unfortunately this pauses the background thread which I don't want to happen.

So my question: is there a way to check if the UI thread is too busy, crowded, etc. to be able to throw some of the updates away? I assume this is what Swing does under the hood, because heap space consumption goes up and down massively, but it never piles up.

Cheers,
Andy
Re: Runnable, RunnableLock instances accumulating on asyncExec [message #1731281 is a reply to message #1731265] Wed, 04 May 2016 06:57 Go to previous messageGo to next message
Erdal Karaca is currently offline Erdal KaracaFriend
Messages: 854
Registered: July 2009
Senior Member
Seems to be a flood of the SWT messages queue.
Maybe, you could exec the draw operation delayed using Display.timerExec()
If you would use 16 ms as delay, you would still get 60 frames/second.

Andy Junius wrote on Wed, 04 May 2016 05:07
I'm still trying to get into SWT, so maybe that's a beginner question:

I'm working on a time domain plot using Canvas. I implemented this component using JavaFX, Swing and SWT because we have performance issues with JavaFX.

The data gets updated faster than the canvas is able to repaint. So, in Swing I do the following:
    // ...
    SwingUtilities.invokeLater(() -> updateView(data));

void updateView(GraphData data) {
    this.currentGraphData = data;
    this.repaint();
}

This works nicely and it's also performant enough.

A similar approach for my SWT component:
    // ...
    this.getDisplay().asyncExec(() -> updateView(data));

void updateView(GraphData data) {
    if (!this.isDisposed()) {
        this.currentGraphData = data;
        this.redraw(); 
    }
}

This works also nicely, although it seems to be a bit less performant. However it looks like I had a memory leak, because heap space increases over time. This is caused by org.eclipse.swt.widgets.RunnableLock and the Runnable itself accumulating. I'll get a constant heap consumption when I use syncExec instead of asyncExec, unfortunately this pauses the background thread which I don't want to happen.

So my question: is there a way to check if the UI thread is too busy, crowded, etc. to be able to throw some of the updates away? I assume this is what Swing does under the hood, because heap space consumption goes up and down massively, but it never piles up.

Cheers,
Andy

Re: Runnable, RunnableLock instances accumulating on asyncExec [message #1731283 is a reply to message #1731281] Wed, 04 May 2016 07:10 Go to previous messageGo to next message
Erdal Karaca is currently offline Erdal KaracaFriend
Messages: 854
Registered: July 2009
Senior Member
Actually, Display.timerExec() would not help here, so you will have to manually decrease rendering speed, for example, using ScheduledExecutorService.schedule(...).
Re: Runnable, RunnableLock instances accumulating on asyncExec [message #1731396 is a reply to message #1731265] Wed, 04 May 2016 23:19 Go to previous message
Andy Junius is currently offline Andy JuniusFriend
Messages: 8
Registered: February 2014
Junior Member
OK, I found a solution; maybe not the best one, but it certainly does the job:

	// control flag
	volatile boolean updateRunning = false;

	// gets called on model updates
    public void setCurrentGraphData(GraphData data) {
        new Thread(new UpdateCanvas(data)).start();        
    }
    
    // this requests the actual redraw
    void updateView(GraphData data) {
        if (!this.isDisposed()) {
            this.currentGraphData = data;           
            this.redraw();
        }
    }    
    
	private class UpdateCanvas implements Runnable {
	
        private final GraphData data;
        
        UpdateCanvas(GraphData data) {
            super();
            this.data=data;
        }
        
        @Override
        public void run() {
            if(!updateRunning) {
                updateRunning = true;                
                 getDisplay().syncExec(() -> updateView(data));
                updateRunning = false;
            }
        }        
    }


Heap space consumption is now a lot less than the one of the Swing component and it's constant. I'll finally have to reduce the amount of updates, but this was a very nice exercise.

Cheers,
Andy
Previous Topic:Future of SWT
Next Topic:Shell getBound() and getLocation() not returning updated value on mac after moving shell
Goto Forum:
  


Current Time: Thu Apr 25 09:18:18 GMT 2024

Powered by FUDForum. Page generated in 0.02952 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top