Skip to content

Commit c0d2a25

Browse files
committed
Fix memory-leak in FigureUtilities by disposing GC on font change
Before this change figureUtilities created a GC once for an application and then reused it to calculate font/text dimensions. Due to the recent modification of GC in SWT to store Operations, every operation on FigureUtilities that sets the font on the GC (i.e., that calls setFont()) creates a SetFontOperation in the GC. Since that GC is never disposed, these operation accumulate throughout the application lifecycle and constituted a memory leak The current change addresses this issue by instead of crearting a single GC we create a single shell for the lifetime of the application. Whenever a different font needs to be set, the old GC is properly disposed and replaced with a new one created from the shell. This ensures that no GC objects persist indefinitely, effectively preventing the memory leak.
1 parent 8726ed7 commit c0d2a25

File tree

1 file changed

+20
-9
lines changed

1 file changed

+20
-9
lines changed

org.eclipse.draw2d/src/org/eclipse/draw2d/FigureUtilities.java

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ public class FigureUtilities {
3232

3333
private static final float RGB_VALUE_MULTIPLIER = 0.6f;
3434
private static GC gc;
35+
private static Shell shell;
3536
private static Font appliedFont;
3637
private static FontMetrics metrics;
3738
private static Color ghostFillColor = new Color(null, 31, 31, 31);
@@ -59,7 +60,7 @@ public static Color darker(Color color) {
5960
public static FontMetrics getFontMetrics(Font f) {
6061
setFont(f);
6162
if (metrics == null) {
62-
metrics = getGC().getFontMetrics();
63+
metrics = gc.getFontMetrics();
6364
}
6465
return metrics;
6566
}
@@ -74,14 +75,20 @@ public static FontMetrics getFontMetrics(Font f) {
7475
@Deprecated
7576
protected static GC getGC() {
7677
if (gc == null) {
77-
Shell shell = new Shell();
78+
gc = new GC(getShell());
79+
appliedFont = gc.getFont();
80+
}
81+
return gc;
82+
}
83+
84+
private static Shell getShell() {
85+
if (shell == null) {
86+
shell = new Shell();
7887
InternalDraw2dUtils.configureForAutoscalingMode(shell, event -> {
7988
// ignored
8089
});
81-
gc = new GC(shell);
82-
appliedFont = gc.getFont();
8390
}
84-
return gc;
91+
return shell;
8592
}
8693

8794
/**
@@ -95,7 +102,7 @@ protected static GC getGC() {
95102
*/
96103
protected static org.eclipse.swt.graphics.Point getTextDimension(String s, Font f) {
97104
setFont(f);
98-
return getGC().textExtent(s);
105+
return gc.textExtent(s);
99106
}
100107

101108
/**
@@ -123,7 +130,7 @@ public static IFigure getRoot(IFigure figure) {
123130
*/
124131
protected static org.eclipse.swt.graphics.Point getStringDimension(String s, Font f) {
125132
setFont(f);
126-
return getGC().stringExtent(s);
133+
return gc.stringExtent(s);
127134
}
128135

129136
/**
@@ -341,10 +348,14 @@ public static void paintEtchedBorder(Graphics g, Rectangle r) {
341348
* @since 2.0
342349
*/
343350
protected static void setFont(Font f) {
344-
if (appliedFont == f || (f != null && f.equals(appliedFont))) {
351+
if ((appliedFont == null && f == null && gc != null) || (f != null && f.equals(appliedFont))) {
345352
return;
346353
}
347-
getGC().setFont(f);
354+
if (gc != null && !gc.isDisposed()) {
355+
gc.dispose();
356+
}
357+
gc = new GC(getShell());
358+
gc.setFont(f);
348359
appliedFont = f;
349360
metrics = null;
350361
}

0 commit comments

Comments
 (0)