Community
Participate
Working Groups
To reproduce, run the following snippet with VM arguments "-Xmx128M -Xms128M -XX:+AlwaysPreTouch": public static void main(String[] args) { Display display = new Display(); Shell shell = new Shell(display); shell.setSize(600, 400); shell.setLayout(new FillLayout()); shell.setText("Demo ToolItem leak"); Composite composite = new Composite(shell, SWT.NONE); composite.setLayout(new FillLayout(SWT.VERTICAL)); ToolBar tb = new ToolBar(composite, SWT.BORDER); shell.open(); AtomicBoolean c = new AtomicBoolean(true); Thread t = new Thread(new Runnable() { @Override public void run() { while (c.get()) { if (!display.isDisposed()) { display.asyncExec(new Runnable() { @Override public void run() { if (!display.isDisposed()) { ToolItem ti = new ToolItem(tb, SWT.BORDER | SWT.DROP_DOWN); ti.setToolTipText("ToolItem text"); ti.dispose(); } } }); } try { Thread.sleep(100); } catch (InterruptedException e) { } } } }); t.start(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) display.sleep(); } c.set(false); try { t.join(); } catch (InterruptedException e) { } display.dispose(); } Observe growing memory consumption. valgrind reports e.g. such leaks: ==29829== 147,168 (72,888 direct, 74,280 indirect) bytes in 3,037 blocks are definitely lost in loss record 11 of 42,451 ==29829== at 0x4C2B017: malloc (vg_replace_malloc.c:380) ==29829== by 0x2A42068D: g_malloc (in /usr/lib64/libglib-2.0.so.0.5600.1) ==29829== by 0x2A437C8D: g_slice_alloc (in /usr/lib64/libglib-2.0.so.0.5600.1) ==29829== by 0x2A416E45: g_list_prepend (in /usr/lib64/libglib-2.0.so.0.5600.1) ==29829== by 0x26E9A4BE: gtk_container_children_callback (gtkcontainer.c:3307) ==29829== by 0x26E568F6: gtk_box_forall (gtkbox.c:2671) ==29829== by 0x26E9FDCA: gtk_container_get_children (gtkcontainer.c:2539) ==29829== by 0x26AF7877: Java_org_eclipse_swt_internal_gtk3_GTK3_gtk_1container_1get_1children (in /home/sandreev/git/eclipse/eclipse.platform.swt.binaries/bundles/org.eclipse.swt.gtk.linux.x86_64/libswt-pi3-gtk-4944r22.so) There seem to be 3 callers of GTK3.gtk_container_get_children() in ToolItem, that don't call OS.g_free(): 1. ToolItem.createHandle(int) 2. ToolItem.hookEvents() 3. ToolItem.setToolTipText(Shell, String) Comment from Alexander Miloslavskiy: > Documentation [1] indicates "transfer > container", therefore, SWT must free the list itself, but not the > elements inside. Also, it easy to see that even SWT does it properly in > other places. > > [1] > https://developer.gnome.org/gtk3/stable/GtkContainer.html#gtk-container-get-children
New Gerrit change created: https://git.eclipse.org/r/c/platform/eclipse.platform.swt/+/180522
Gerrit change https://git.eclipse.org/r/c/platform/eclipse.platform.swt/+/180522 was merged to [master]. Commit: http://git.eclipse.org/c/platform/eclipse.platform.swt.git/commit/?id=ea642afb7d222fb92253f05dc8f895f605e3208b
I trace one of the calls to gtk_container_get_children() without a matching free (the one in ToolItem.createHandle()) back to bug 46025, see commit: https://git.eclipse.org/c/platform/eclipse.platform.swt.git/commit/?id=1c6100db3e7e2869dd9939a388c01ffe02266ae6 And in particular: https://git.eclipse.org/c/platform/eclipse.platform.swt.git/diff/bundles/org.eclipse.swt/Eclipse%20SWT/gtk/org/eclipse/swt/widgets/ToolItem.java?id=1c6100db3e7e2869dd9939a388c01ffe02266ae6 The code did get moved around a couple of times, but I think this is the first commit that adds it. Its of course possible that GTK changed to require a free, but that seems unlikely (I don't know much about GTK API evolution though, I might be wrong).