Skip to content

Commit 89f0bcc

Browse files
ShahzaibIbrahimHeikoKlare
authored andcommitted
Fix Resource leak tracking issue on Windows
On Windows, SWT resources supporting multiple zoom levels are registered via Device.registerResourceWithZoomSupport(), which retains strong references to these resources. This prevents garbage collection and breaks leak detection using Cleaner. Switching to use WeakReference to allow proper GC behavior and enable the resource tracker to report non-disposed resources correctly. Fixes: #2335
1 parent 7cf1145 commit 89f0bcc

File tree

1 file changed

+34
-4
lines changed
  • bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics

1 file changed

+34
-4
lines changed

bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Device.java

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
package org.eclipse.swt.graphics;
1515

1616

17+
import java.lang.ref.*;
1718
import java.util.*;
1819
import java.util.concurrent.*;
1920

@@ -61,7 +62,7 @@ public abstract class Device implements Drawable {
6162
String[] loadedFonts;
6263

6364
volatile boolean disposed;
64-
private Set<Resource> resourcesWithZoomSupport = ConcurrentHashMap.newKeySet();
65+
private Set<ResourceReference> resourcesWithZoomSupport = ConcurrentHashMap.newKeySet();
6566

6667
/*
6768
* TEMPORARY CODE. When a graphics object is
@@ -964,11 +965,11 @@ protected int getDeviceZoom () {
964965
}
965966

966967
void registerResourceWithZoomSupport(Resource resource) {
967-
resourcesWithZoomSupport.add(resource);
968+
resourcesWithZoomSupport.add(new ResourceReference(resource));
968969
}
969970

970971
void deregisterResourceWithZoomSupport(Resource resource) {
971-
resourcesWithZoomSupport.remove(resource);
972+
resourcesWithZoomSupport.remove(new ResourceReference(resource));
972973
}
973974

974975
/**
@@ -982,8 +983,37 @@ public static void win32_destroyUnusedHandles(Display display) {
982983
for (Monitor monitor : display.getMonitors()) {
983984
availableZoomLevels.add(DPIUtil.getZoomForAutoscaleProperty(monitor.getZoom()));
984985
}
985-
for (Resource resource: ((Device) display).resourcesWithZoomSupport) {
986+
Set<ResourceReference> resources = ((Device) display).resourcesWithZoomSupport;
987+
Iterator<ResourceReference> iterator = resources.iterator();
988+
989+
while (iterator.hasNext()) {
990+
ResourceReference ref = iterator.next();
991+
Resource resource = ref.get();
992+
if (resource == null) {
993+
iterator.remove(); // Clean up dead reference.
994+
continue;
995+
}
986996
resource.destroyHandlesExcept(availableZoomLevels);
987997
}
988998
}
999+
1000+
private static class ResourceReference extends WeakReference<Resource> {
1001+
1002+
public ResourceReference(Resource referent) {
1003+
super(referent);
1004+
}
1005+
1006+
@Override
1007+
public boolean equals(Object obj) {
1008+
if(this == obj) return true;
1009+
if (!(obj instanceof ResourceReference passedResource)) return false;
1010+
return Objects.equals(this.get(), passedResource.get());
1011+
}
1012+
1013+
@Override
1014+
public int hashCode() {
1015+
Resource resource = this.get();
1016+
return resource != null ? resource.hashCode() : 0;
1017+
}
1018+
}
9891019
}

0 commit comments

Comments
 (0)