Skip to content

Commit 27a3a4e

Browse files
committed
Free heap-space (hires models) if the renderer didnt use it for more than one minute
1 parent 902e76a commit 27a3a4e

File tree

2 files changed

+58
-2
lines changed

2 files changed

+58
-2
lines changed

core/src/main/java/de/bluecolored/bluemap/core/map/hires/ArrayTileModel.java

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,30 @@
3030
import de.bluecolored.bluemap.core.util.math.MatrixM3f;
3131
import de.bluecolored.bluemap.core.util.math.MatrixM4f;
3232

33+
import java.time.Duration;
34+
import java.time.Instant;
35+
3336
public class ArrayTileModel implements TileModel {
34-
private static final double GROW_MULTIPLIER = 1.5;
37+
private static final float GROW_MULTIPLIER = 1.5f;
3538
private static final int MAX_CAPACITY = 1000000;
3639

40+
private static final float SHRINK_MULTIPLIER = 1 / GROW_MULTIPLIER;
41+
private static final Duration SHRINK_TIME = Duration.ofMinutes(1);
42+
3743
private static final InstancePool<ArrayTileModel> INSTANCE_POOL = new InstancePool<>(
3844
() -> new ArrayTileModel(100),
39-
ArrayTileModel::clear
45+
model -> {
46+
Instant now = Instant.now();
47+
48+
if ((float) model.size / model.capacity > SHRINK_MULTIPLIER)
49+
model.lastCapacityUse = now;
50+
else if (model.lastCapacityUse.plus(SHRINK_TIME).isBefore(now))
51+
return null; // drop model
52+
53+
model.clear();
54+
return model;
55+
},
56+
Duration.ofMinutes(1)
4057
);
4158

4259
// attributes per-vertex * per-face
@@ -57,6 +74,8 @@ public class ArrayTileModel implements TileModel {
5774
byte[] sunlight, blocklight;
5875
int[] materialIndex, materialIndexSort, materialIndexSortSupport;
5976

77+
private transient Instant lastCapacityUse = Instant.now();
78+
6079
public ArrayTileModel(int initialCapacity) {
6180
if (initialCapacity < 0) throw new IllegalArgumentException("initialCapacity is negative");
6281
setCapacity(initialCapacity);

core/src/main/java/de/bluecolored/bluemap/core/util/InstancePool.java

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,38 +24,75 @@
2424
*/
2525
package de.bluecolored.bluemap.core.util;
2626

27+
import de.bluecolored.bluemap.core.logger.Logger;
28+
import org.jetbrains.annotations.Nullable;
29+
30+
import java.time.Duration;
31+
import java.util.Timer;
32+
import java.util.TimerTask;
2733
import java.util.concurrent.ConcurrentLinkedQueue;
2834
import java.util.function.Function;
2935
import java.util.function.Supplier;
3036

3137
public class InstancePool<T> {
3238

39+
private static final class AutoClearTimer {
40+
private static final Timer INSTANCE = new Timer("BlueMap-InstancePool-RecycleTimer", true);
41+
}
42+
3343
private final Supplier<T> creator;
3444
private final Function<T, T> recycler;
3545
private final ConcurrentLinkedQueue<T> pool = new ConcurrentLinkedQueue<>();
46+
private final @Nullable Duration autoClearTime;
47+
private @Nullable TimerTask autoClearTask = null;
3648

3749
public InstancePool(Supplier<T> creator) {
3850
this.creator = creator;
3951
this.recycler = t -> t;
52+
this.autoClearTime = null;
4053
}
4154

4255
public InstancePool(Supplier<T> creator, Function<T, T> recycler) {
4356
this.creator = creator;
4457
this.recycler = recycler;
58+
this.autoClearTime = null;
59+
}
60+
61+
public InstancePool(Supplier<T> creator, Function<T, T> recycler, @Nullable Duration autoClearTime) {
62+
this.creator = creator;
63+
this.recycler = recycler;
64+
this.autoClearTime = autoClearTime;
65+
updateAutoClear();
66+
}
67+
68+
private void updateAutoClear() {
69+
if (autoClearTask != null) autoClearTask.cancel();
70+
if (autoClearTime != null) {
71+
autoClearTask = new TimerTask() {
72+
@Override
73+
public void run() {
74+
Logger.global.logInfo("Auto-clearing pool now!");
75+
InstancePool.this.clear();
76+
}
77+
};
78+
AutoClearTimer.INSTANCE.schedule(autoClearTask, autoClearTime.toMillis());
79+
}
4580
}
4681

4782
public T claimInstance() {
4883
T instance = pool.poll();
4984
if (instance == null) {
5085
instance = creator.get();
5186
}
87+
updateAutoClear();
5288
return instance;
5389
}
5490

5591
public void recycleInstance(T instance) {
5692
instance = recycler.apply(instance);
5793
if (instance != null)
5894
pool.offer(instance);
95+
updateAutoClear();
5996
}
6097

6198
public void clear() {

0 commit comments

Comments
 (0)