Avoid odd behavior where Sponge prevents User subjects from being GCed

This commit is contained in:
Luck 2016-10-09 21:34:05 +01:00
parent 1eb053447e
commit 069e535f1a
No known key found for this signature in database
GPG Key ID: EFA9B3EC5FD90F8B
4 changed files with 25 additions and 9 deletions

View File

@ -36,7 +36,6 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors; import java.util.stream.Collectors;
public class ContextData { public class ContextData {
private final LuckPermsUserSubject parent;
@Getter @Getter
private final Map<String, String> context; private final Map<String, String> context;
@ -47,7 +46,6 @@ public class ContextData {
private final PermissionCalculator calculator; private final PermissionCalculator calculator;
public ContextData(LuckPermsUserSubject parent, Map<String, String> context, LuckPermsService service) { public ContextData(LuckPermsUserSubject parent, Map<String, String> context, LuckPermsService service) {
this.parent = parent;
this.context = context; this.context = context;
Set<Context> contexts = context.entrySet().stream().map(e -> new Context(e.getKey(), e.getValue())).collect(Collectors.toSet()); Set<Context> contexts = context.entrySet().stream().map(e -> new Context(e.getKey(), e.getValue())).collect(Collectors.toSet());

View File

@ -50,10 +50,10 @@ public class LuckPermsSubject implements Subject {
} }
@Getter @Getter
private final PermissionHolder holder; private PermissionHolder holder;
private final LuckPermsSubjectData enduringData; private LuckPermsSubjectData enduringData;
private final LuckPermsSubjectData transientData; private LuckPermsSubjectData transientData;
protected final LuckPermsService service; protected LuckPermsService service;
LuckPermsSubject(PermissionHolder holder, LuckPermsService service) { LuckPermsSubject(PermissionHolder holder, LuckPermsService service) {
this.holder = holder; this.holder = holder;
@ -62,6 +62,13 @@ public class LuckPermsSubject implements Subject {
this.service = service; this.service = service;
} }
public void deprovision() {
holder = null;
enduringData = null;
transientData = null;
service = null;
}
void objectSave(PermissionHolder t) { void objectSave(PermissionHolder t) {
service.getPlugin().doAsync(() -> { service.getPlugin().doAsync(() -> {
if (t instanceof User) { if (t instanceof User) {

View File

@ -45,10 +45,10 @@ public class LuckPermsUserSubject extends LuckPermsSubject {
} }
@Getter @Getter
private final User user; private User user;
@Getter @Getter
private final Map<Map<String, String>, ContextData> contextData; private Map<Map<String, String>, ContextData> contextData;
private LuckPermsUserSubject(User user, LuckPermsService service) { private LuckPermsUserSubject(User user, LuckPermsService service) {
super(user, service); super(user, service);
@ -57,6 +57,15 @@ public class LuckPermsUserSubject extends LuckPermsSubject {
contextData = new ConcurrentHashMap<>(); contextData = new ConcurrentHashMap<>();
} }
@Override
public void deprovision() {
/* For some reason, Sponge holds onto User instances in a cache, which in turn, prevents LuckPerms data from being GCed.
As well as unloading, we also remove all references to the User instances. */
super.deprovision();
user = null;
contextData = null;
}
@Override @Override
public Tristate getPermissionValue(@NonNull Set<Context> contexts, @NonNull String permission) { public Tristate getPermissionValue(@NonNull Set<Context> contexts, @NonNull String permission) {
Map<String, String> context = contexts.stream().collect(Collectors.toMap(Context::getKey, Context::getValue)); Map<String, String> context = contexts.stream().collect(Collectors.toMap(Context::getKey, Context::getValue));

View File

@ -92,7 +92,9 @@ public class UserCollection implements SubjectCollection {
* @param uuid the internal uuid of the user * @param uuid the internal uuid of the user
*/ */
public void unload(UUID uuid) { public void unload(UUID uuid) {
users.remove(uuid); if (users.containsKey(uuid)) {
users.remove(uuid).deprovision();
}
} }
@Override @Override