我正在看
Remember to call close() on all Realm instances. Realm /data/data/com.org.example/files/default.realm is being finalized without being closed, this can lead to running out of native memory.
即使我在.close()
的每次通话后都清楚地拨打了getInstance(realmConfig)
。
大部分时间看起来像这样:
Realm realm = Realm.getInstance(realmConfig);
try {
realm.beginTransaction();
realm.copyToRealmOrUpdate(someData);
realm.commitTransaction();
} catch (Exception e) {
realm.cancelTransaction();
} finally {
if (realm != null) {
realm.close();
}
}
其他时候看起来像(使用Rx Observable Pattern):
@Override
public void call(Subscriber<? super JsonElement> subscriber) {
SomeJson someJson = Realm.getInstance(mRealmConfig).where(SomeJson.class)
.equalTo("type", type)
.equalTo("id", id)
.findFirst();
if (someJson == null || !someJson.isDataValid()) {
Logger.d(TAG, "Did not find value for id: " + id + " for type: " + type);
subscriber.onNext(null);
subscriber.onCompleted();
Realm.getInstance(mRealmConfig).close();
return;
}
JsonElement val = (new JsonParser()).parse(someJson.jsonString);
subscriber.onNext(val);
subscriber.onCompleted();
Realm.getInstance(mRealmConfig).close();
}
知道我为什么还会收到这些警告?
答案 0 :(得分:6)
Realm realm = Realm.getInstance(mRealmConfig);
// ...
Realm.getInstance(mRealmConfig).close();
问题出在这里。您已获得其他 Realm
并关闭它,但您尚未关闭orignal realm
。
你应该对所有这些使用try-with-resources:
try (Realm realm = Realm.getInstance(realmConfig)) {
realm.beginTransaction();
realm.copyToRealmOrUpdate(someData);
realm.commitTransaction();
} catch (Exception e) {
realm.cancelTransaction();
}
[请注意,realm
在您测试时永远不会为空,如果是,它会更快地触发NPE。]
和
@Override
public void call(Subscriber<? super JsonElement> subscriber) {
try (Realm realm = Realm.getInstance(mRealmConfig)) {
SomeJson someJson = realm.where(SomeJson.class)
.equalTo("type", type)
.equalTo("id", id)
.findFirst();
if (someJson == null || !someJson.isDataValid()) {
Logger.d(TAG, "Did not find value for id: " + id + " for type: " + type);
subscriber.onNext(null);
subscriber.onCompleted();
return;
}
JsonElement val = (new JsonParser()).parse(someJson.jsonString);
subscriber.onNext(val);
subscriber.onCompleted();
}
}
答案 1 :(得分:4)
每次调用Realm.getInstance(mRealmConfig)
时,都会在当前线程中创建对此Realm
实例的本地引用。
您需要在所有引用上调用close()
才能真正关闭Realm
实例。
在您的Rx实现中,您调用Realm.getInstance(mRealmConfig)
三次,因此创建了三个本地引用,其中两个已关闭。
您可以创建一个引用并一劳永逸地关闭它(就像您在第一个代码段中所做的那样)
@Override
public void call(Subscriber<? super JsonElement> subscriber) {
Realm realm = Realm.getInstance(mRealmConfig);
SomeJson someJson = realm.where(SomeJson.class)
.equalTo("type", type)
.equalTo("id", id)
.findFirst();
if (someJson == null || !someJson.isDataValid()) {
Logger.d(TAG, "Did not find value for id: " + id + " for type: " + type);
subscriber.onNext(null);
subscriber.onCompleted();
realm.close();
return;
}
JsonElement val = (new JsonParser()).parse(someJson.jsonString);
subscriber.onNext(val);
subscriber.onCompleted();
realm.close();
}