Skip to content

Commit e962016

Browse files
committed
Use weak reference to allow resource release while nobody using it
1 parent 3410b25 commit e962016

File tree

3 files changed

+44
-12
lines changed

3 files changed

+44
-12
lines changed

src/main/java/org/maxgamer/quickshop/util/reload/ReloadManager.java

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import org.jetbrains.annotations.NotNull;
2323
import org.jetbrains.annotations.Nullable;
2424

25+
import java.lang.ref.WeakReference;
2526
import java.lang.reflect.Method;
2627
import java.util.*;
2728

@@ -40,7 +41,7 @@ public class ReloadManager {
4041
*/
4142
public void register(@NotNull Reloadable reloadable) {
4243
unregister(reloadable);
43-
this.registry.add(new ReloadableContainer(reloadable, null));
44+
this.registry.add(new ReloadableContainer(new WeakReference<>(reloadable), null));
4445
}
4546

4647
/**
@@ -50,7 +51,7 @@ public void register(@NotNull Reloadable reloadable) {
5051
*/
5152
public void register(@NotNull Method reloadMethod) {
5253
unregister(reloadMethod);
53-
this.registry.add(new ReloadableContainer(null, reloadMethod));
54+
this.registry.add(new ReloadableContainer(null, new WeakReference<>(reloadMethod)));
5455
}
5556

5657
/**
@@ -59,8 +60,14 @@ public void register(@NotNull Method reloadMethod) {
5960
* @param reloadMethod Reloadable module
6061
*/
6162
public void unregister(@NotNull Method reloadMethod) {
62-
this.registry.removeIf(reloadableContainer -> reloadableContainer.getReloadableMethod() != null
63-
&& reloadableContainer.getReloadableMethod().equals(reloadMethod));
63+
this.registry.removeIf(reloadableContainer -> {
64+
if (reloadableContainer.getReloadableMethod() != null) {
65+
Method method = reloadableContainer.getReloadableMethod().get();
66+
return reloadMethod.equals(method);
67+
} else {
68+
return false;
69+
}
70+
});
6471
}
6572

6673

@@ -84,7 +91,9 @@ public void unregister(@NotNull Class<Reloadable> clazz) {
8491
return clazz.equals(reloadable.getReloadable().getClass());
8592
}
8693
if (reloadable.getReloadableMethod() != null) {
87-
return clazz.equals(reloadable.getReloadableMethod().getDeclaringClass());
94+
Method method = reloadable.getReloadableMethod().get();
95+
if (method != null)
96+
return clazz.equals(method.getDeclaringClass());
8897
}
8998
return false;
9099
});
@@ -109,25 +118,42 @@ public Map<ReloadableContainer, ReloadResult> reload() {
109118
@NotNull
110119
public Map<ReloadableContainer, ReloadResult> reload(@Nullable Class<Reloadable> clazz) {
111120
Map<ReloadableContainer, ReloadResult> reloadResultMap = new HashMap<>();
112-
for (ReloadableContainer reloadable : this.registry) {
121+
Iterator<ReloadableContainer> iterator = this.registry.iterator();
122+
while (iterator.hasNext()) {
123+
ReloadableContainer reloadable = iterator.next();
113124
if (clazz != null) {
114125
if (reloadable.getReloadable() != null) {
115126
if (!clazz.equals(reloadable.getReloadable().getClass())) {
116127
continue;
117128
}
118129
}
119130
if (reloadable.getReloadableMethod() != null) {
120-
if (!clazz.equals(reloadable.getReloadableMethod().getDeclaringClass())) {
121-
continue;
131+
Method method = reloadable.getReloadableMethod().get();
132+
if (method != null) {
133+
if (!clazz.equals(method.getDeclaringClass())) {
134+
continue;
135+
}
122136
}
123137
}
124138
}
125139
ReloadResult reloadResult;
126140
try {
127141
if (reloadable.getReloadable() != null) {
128-
reloadResult = reloadable.getReloadable().reloadModule();
142+
Reloadable reloadObj = reloadable.getReloadable().get();
143+
if (reloadObj != null) {
144+
reloadResult = reloadObj.reloadModule();
145+
} else {
146+
iterator.remove();
147+
reloadResult = new ReloadResult(ReloadStatus.OUTDATED, "Object has been invalid", null);
148+
}
129149
} else if (reloadable.getReloadableMethod() != null) {
130-
reloadResult = (ReloadResult) reloadable.getReloadableMethod().invoke(null);
150+
Method method = reloadable.getReloadableMethod().get();
151+
if (method != null) {
152+
reloadResult = (ReloadResult) method.invoke(null);
153+
} else {
154+
iterator.remove();
155+
reloadResult = new ReloadResult(ReloadStatus.OUTDATED, "Method has been invalid", null);
156+
}
131157
} else {
132158
reloadResult = new ReloadResult(ReloadStatus.EXCEPTION, "Both reloadable and method not exists", null);
133159
}

src/main/java/org/maxgamer/quickshop/util/reload/ReloadStatus.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ public enum ReloadStatus {
2424
* Reload successes
2525
*/
2626
SUCCESS,
27+
/**
28+
* The object that registered now no reference and has been GC by Java.
29+
*/
30+
OUTDATED,
2731
/**
2832
* Reload require the server restart
2933
*/
@@ -36,4 +40,5 @@ public enum ReloadStatus {
3640
* Oof, reloading exploded, wtf
3741
*/
3842
EXCEPTION,
43+
3944
}

src/main/java/org/maxgamer/quickshop/util/reload/ReloadableContainer.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,16 +24,17 @@
2424
import lombok.Data;
2525
import org.jetbrains.annotations.Nullable;
2626

27+
import java.lang.ref.WeakReference;
2728
import java.lang.reflect.Method;
2829

2930
@Data
3031
@Builder
3132
@AllArgsConstructor
3233
public class ReloadableContainer {
3334
@Nullable
34-
private Reloadable reloadable;
35+
private WeakReference<Reloadable> reloadable;
3536
@Nullable
36-
private Method reloadableMethod;
37+
private WeakReference<Method> reloadableMethod;
3738

3839
public boolean isObject() {
3940
return reloadable != null;

0 commit comments

Comments
 (0)