Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Williams2019-06-18 16:03:18 -0400
committerEric Williams2019-06-19 10:15:57 -0400
commit1a722935d5c4937bbfa79b2970b3574752be9070 (patch)
tree5939ab0b0c7e5029aec5041709d59e0dc81d6501
parentd9f48342306be62cedf7b7cc6e1fb468c5255d45 (diff)
downloadeclipse.platform.swt-1a722935d5c4937bbfa79b2970b3574752be9070.tar.gz
eclipse.platform.swt-1a722935d5c4937bbfa79b2970b3574752be9070.tar.xz
eclipse.platform.swt-1a722935d5c4937bbfa79b2970b3574752be9070.zip
Bug 547227: [GTK3] Group widget causes memory leak and slowdown
Do not call g_object_ref() before/after g_object_ref_sink(). GObject already adds a reference when calling g_object_ref_sink(). Tested using a child Eclipse, and the snippet provided. No AllNonBrowser JUnit tests fail. Test environment: Fedora 30, GTK3.24, Wayland. Change-Id: I3c6b0222e7342626439688883142cd646857a1ba Signed-off-by: Eric Williams <ericwill@redhat.com>
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Button.java1
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Group.java1
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/MenuItem.java1
-rw-r--r--tests/org.eclipse.swt.tests.gtk/ManualTests/org/eclipse/swt/tests/gtk/snippets/Bug547227_GroupMemoryLeak.java81
4 files changed, 81 insertions, 3 deletions
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Button.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Button.java
index 32c59c5e4b..723774be59 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Button.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Button.java
@@ -331,7 +331,6 @@ void createHandle (int index) {
*/
groupHandle = GTK.gtk_radio_button_new (0);
if (groupHandle == 0) error (SWT.ERROR_NO_HANDLES);
- OS.g_object_ref (groupHandle);
OS.g_object_ref_sink (groupHandle);
handle = GTK.gtk_radio_button_new (GTK.gtk_radio_button_get_group (groupHandle));
if (handle == 0) error (SWT.ERROR_NO_HANDLES);
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Group.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Group.java
index 4b984feb7e..73387c316f 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Group.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Group.java
@@ -191,7 +191,6 @@ void createHandle(int index) {
labelHandle = GTK.gtk_label_new (null);
if (labelHandle == 0) error (SWT.ERROR_NO_HANDLES);
- OS.g_object_ref (labelHandle);
OS.g_object_ref_sink (labelHandle);
clientHandle = OS.g_object_new (display.gtk_fixed_get_type (), 0);
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/MenuItem.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/MenuItem.java
index e95b49733d..525fdb9d3d 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/MenuItem.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/MenuItem.java
@@ -277,7 +277,6 @@ void createHandle (int index) {
*/
groupHandle = GTK.gtk_radio_menu_item_new (0);
if (groupHandle == 0) error (SWT.ERROR_NO_HANDLES);
- OS.g_object_ref (groupHandle);
OS.g_object_ref_sink (groupHandle);
long group = GTK.gtk_radio_menu_item_get_group (groupHandle);
handle = GTK.gtk_radio_menu_item_new (group);
diff --git a/tests/org.eclipse.swt.tests.gtk/ManualTests/org/eclipse/swt/tests/gtk/snippets/Bug547227_GroupMemoryLeak.java b/tests/org.eclipse.swt.tests.gtk/ManualTests/org/eclipse/swt/tests/gtk/snippets/Bug547227_GroupMemoryLeak.java
new file mode 100644
index 0000000000..45b25b62f4
--- /dev/null
+++ b/tests/org.eclipse.swt.tests.gtk/ManualTests/org/eclipse/swt/tests/gtk/snippets/Bug547227_GroupMemoryLeak.java
@@ -0,0 +1,81 @@
+/*******************************************************************************
+ * Copyright (c) 2019 Patrick Tasse and others. All rights reserved.
+ * The contents of this file are made available under the terms
+ * of the GNU Lesser General Public License (LGPL) Version 2.1 that
+ * accompanies this distribution (lgpl-v21.txt). The LGPL is also
+ * available at http://www.gnu.org/licenses/lgpl.html. If the version
+ * of the LGPL at http://www.gnu.org is different to the version of
+ * the LGPL accompanying this distribution and there is any conflict
+ * between the two license versions, the terms of the LGPL accompanying
+ * this distribution shall govern.
+ *
+ * Contributors:
+ * Patrick Tasse - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.swt.tests.gtk.snippets;
+
+import java.util.Arrays;
+import java.util.function.Function;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Widget;
+
+public class Bug547227_GroupMemoryLeak {
+
+ private static final int NUM_ITERATIONS = 20;
+ private static final int NUM_WIDGETS = 400;
+
+ public static void main(String[] args) {
+ Display display = new Display();
+ System.out.println("gtk version: " + System.getProperty("org.eclipse.swt.internal.gtk.version"));
+ System.out.println();
+
+ Function<Composite, Widget> compositeCreator = parent -> {
+ Composite composite = new Composite(parent, SWT.NONE);
+ composite.setLayout(new GridLayout());
+ composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
+ return composite;
+ };
+ Function<Composite, Widget> groupCreator = parent -> {
+ Group group = new Group(parent, SWT.NONE);
+ group.setLayout(new GridLayout());
+ group.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
+ return group;
+ };
+ for (Function<Composite, Widget> creator : Arrays.asList(compositeCreator, groupCreator)) {
+ for (int i = 1; i <= NUM_ITERATIONS; i++) {
+ Shell shell = new Shell(display);
+ shell.setLayout(new FillLayout());
+ Composite composite = new Composite(shell, SWT.NONE);
+ composite.setLayout(new GridLayout(40, false));
+ Widget widget = null;
+ for (int k = 0; k < NUM_WIDGETS; k++) {
+ widget = creator.apply(composite);
+ }
+ shell.pack();
+ shell.open();
+ while (display.readAndDispatch()) {
+ }
+ display.sleep();
+ long t1 = System.currentTimeMillis();
+ System.out.print(String.format("shell.dispose() for %s with %d %s [%d]...\t", shell, NUM_WIDGETS, widget.getClass().getSimpleName(), i));
+ shell.dispose();
+ long t2 = System.currentTimeMillis();
+ System.out.print(String.format("%4d ms ", (t2-t1)));
+ for (int n = 0; n < (t2-t1); n+=10) {
+ System.out.print("=");
+ }
+ System.out.println();
+ }
+ System.out.println();
+ }
+ display.dispose();
+ }
+} \ No newline at end of file

Back to the top