From 8d385ef812e8b1413082ddedb98093cadbe6adc5 Mon Sep 17 00:00:00 2001 From: Bane Stojkovic Date: Tue, 5 Jul 2022 00:59:30 +0200 Subject: [PATCH] Limit memory usage to avoid out of memory errors when 'Cache Boost' feature is enabled --- .../src/org/diylc/presenter/DrawingCache.java | 25 ++++++++++++++----- .../src/org/diylc/presenter/update.xml | 8 ++++++ 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/diylc/diylc-core/src/org/diylc/presenter/DrawingCache.java b/diylc/diylc-core/src/org/diylc/presenter/DrawingCache.java index 71f92aa0..1fe2c1fc 100644 --- a/diylc/diylc-core/src/org/diylc/presenter/DrawingCache.java +++ b/diylc/diylc-core/src/org/diylc/presenter/DrawingCache.java @@ -22,10 +22,10 @@ import java.awt.geom.Area; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; import java.awt.image.BufferedImage; +import java.lang.ref.SoftReference; import java.util.HashMap; import java.util.Map; import java.util.stream.Collectors; - import org.apache.log4j.Logger; import org.diylc.common.ComponentType; import org.diylc.core.ComponentState; @@ -44,7 +44,7 @@ import org.diylc.utils.Pair; */ public class DrawingCache { - private Map, CacheValue> imageCache = new HashMap, CacheValue>(); + private Map, SoftReference> imageCache = new HashMap, SoftReference>(); private Map> renderStatsByType = new HashMap>(); @@ -139,9 +139,18 @@ public class DrawingCache { } public void logStats() { - int totalSizeMB = imageCache.values().stream().map(x -> x.image.getData().getDataBuffer().getSize()).reduce(0, Integer::sum) * 4 / 1024 / 1024; // 4 bytes per pixel + int totalSizeMB = imageCache.values() + .stream() + .map(x -> x.get() == null ? 0 : x.get().image.getData().getDataBuffer().getSize()) + .reduce(0, Integer::sum) * 4 / 1024 / 1024; // 4 bytes per pixel LOG.debug(String.format("Render cache contains %d elements, approx size is %d MB", imageCache.size(), totalSizeMB)); + long evictedCount = imageCache.values() + .stream() + .filter(x -> x.get() == null) + .count(); + LOG.debug(String.format("Render cache contains %d evicted entries", evictedCount)); + String mapAsString = renderStatsByType.entrySet().stream().sorted((e1, e2) -> -Long.compare(e1.getValue().getFirst().getNanoTime() + e1.getValue().getSecond().getNanoTime(), e2.getValue().getFirst().getNanoTime() + e2.getValue().getSecond().getNanoTime())) .map(e -> e.getKey() + ": render: " + e.getValue().getFirst() + ", paste: " + e.getValue().getSecond()) @@ -161,8 +170,12 @@ public class DrawingCache { // cache hit! CacheValue value = null; - if (imageCache.containsKey(component)) - value = imageCache.get(component); + if (imageCache.containsKey(component)) { + SoftReference weakReference = imageCache.get(component); + if (weakReference != null) { + value = weakReference.get(); + } + } // only honor the cache if the component hasn't changed in the meantime if (value == null || !value.getComponent().equalsTo(component) @@ -237,7 +250,7 @@ public class DrawingCache { // add to the cache value = new CacheValue(component, image, wrapper.getCurrentArea(), wrapper.getContinuityPositiveAreas(), wrapper.getContinuityNegativeAreas(), componentState, outlineMode, zoom, dx, dy, rect); - imageCache.put(component, value); + imageCache.put(component, new SoftReference(value)); } return value; diff --git a/diylc/diylc-core/src/org/diylc/presenter/update.xml b/diylc/diylc-core/src/org/diylc/presenter/update.xml index 3ff57881..19d12c93 100644 --- a/diylc/diylc-core/src/org/diylc/presenter/update.xml +++ b/diylc/diylc-core/src/org/diylc/presenter/update.xml @@ -3862,10 +3862,18 @@ BUG_FIX Status bar shows a wrong number of selected components + + IMPROVEMENT + Limit memory usage to avoid out of memory errors when 'Cache Boost' feature is enabled + IMPROVEMENT Added BJT BCE pinout to transistor components + + IMPROVEMENT + Changed resistor orange band color to more intense orange + https://github.com/bancika/diy-layout-creator/releases