java - E/REALM_JNI: jni: ThrowingException 5, mmap() failed: Out of memory size: 369098752
问题描述
我正在尝试将大型 json 文件下载到 Realm 数据库中。loadCarbay()
做得很好,但checkTyres()
抛出内存异常Realm.getDefaultInstance()
我在关闭实例时检查了所有领域代码 - 一切都很好。我检查getLocalInstanceCount()
过 - 它在崩溃前返回 0。我无法理解我做错了什么?
void checkLoadData(){
final boolean hasCarbay = hasCarbay();
final boolean hasTyres = hasTyres();
if(!hasPersons()||!hasModels()||!hasDeparts()||!hasCarbay||!hasTyres){
if(checkWifi(this)){
if(!progressDialog.isShowing())progressDialog.show();
Thread t = new Thread(new Runnable() {
public void run() {
final String holding = ses.getString("holding_url");
final String curr = ses.getString("curBaseAAURL");
loadBase(holding,curr,"");
if(!hasPersons()) {
h.sendEmptyMessage(STATUS_LOADING_PERSONS_START);
loadTablePersons(LoginPageActivity.this, h, STATUS_LOADING_PERSONS_PROGRESS, STATUS_LOADING_PERSONS_END);
loadTopicsFromJson(LoginPageActivity.this);
}
if(!hasModels()){
h.sendEmptyMessage(STATUS_LOADING_MODELS_START);
loadAlfaModels(LoginPageActivity.this,h,STATUS_LOADING_ALFA_PROGRESS,STATUS_LOADING_ALFA_END);
}
if(!hasDeparts()){
h.sendEmptyMessage(STATUS_LOADING_WS_LINKS_START);
loadDepartments(LoginPageActivity.this);
h.sendEmptyMessage(STATUS_LOADING_WS_LINKS_END);
}
if(!hasCarbay){
h.sendEmptyMessage(STATUS_LOADING_CARBAY_START);
loadCarbayData(LoginPageActivity.this,h,STATUS_LOADING_CARBAY_END);
h.sendEmptyMessage(STATUS_LOADING_CARBAY_END);
}
if(!hasTyres){
h.sendEmptyMessage(STATUS_LOADING_TYRE_START);
loadTyres(LoginPageActivity.this,h,STATUS_LOADING_TYRE_END);
}
h.sendEmptyMessage(STATUS_LOADING_TYRE_END);
}
}
);
t.start();
}
}
}
private boolean hasCarbay(){
Realm realm = Realm.getDefaultInstance();
long count = realm.where(CarbayBrand.class)
.count();
boolean f = count>0;
realm.close();
return f;
}
private boolean hasTyres(){
boolean flag = false;
Realm realm = Realm.getDefaultInstance();
try{
long count = realm.where(Tyre.class).count();
if(count>0){
Tyre t = realm.where(Tyre.class).findFirst();
if(t!=null){
if(t.getUid()!=null && !t.getUid().isEmpty()){
flag = true;
}
}
}
Log.d("hasTyre","count="+count);
}catch (Exception e){
e.printStackTrace();
}finally {
realm.close();
}
return flag;
}
//loading data to realm
synchronized void loadCarbayData(Context context, Handler h, int LOADING_END){
GlobalParams globalParams = new GlobalParams(context);
final String url1 = "http://" + globalParams.storage_url + "/carbay/car_bay_data.txt";
final String url2 = "http://" + globalParams.storage_url + "/carbay/carbay_ref1.json";
final String url3 = "http://" + globalParams.storage_url + "/carbay/carbay_ref2.json";
final String url4 = "http://" + globalParams.storage_url + "/carbay/carbay_ref3.json";
//Log.d("JsonGet", "Realm closed! Realm instances="+Realm.getLocalInstanceCount(Realm.getDefaultConfiguration()));
Realm realm = Realm.getDefaultInstance();
try{
realm.executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
realm.delete(TradeInCarbay.class);
}
});
realm.executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
realm.delete(CarbayBrand.class);
}
});
realm.executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
realm.delete(CarbayModels.class);
}
});
realm.executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
realm.delete(CarbayModifications.class);
}
});
realm.executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
realm.delete(CarbayDataLink.class);
}
});
// Insert multiple items using an InputStream
Log.d("JsonGet", "Старт загрузки справочника Карбей");
realm.executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
try {
URL url = new URL(url1);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.connect();
InputStream stream = connection.getInputStream();
realm.createAllFromJson(TradeInCarbay.class, stream);
} catch (IOException e) {
e.printStackTrace();
}
}
});
Log.d("JsonGet", "Старт загрузки регистра Карбей ч1");
// Insert multiple items using an InputStream
realm.executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
try {
URL url = new URL(url2);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.connect();
InputStream stream = connection.getInputStream();
realm.createAllFromJson(CarbayBrand.class, stream);
} catch (IOException e) {
e.printStackTrace();
}
}
});
Log.d("JsonGet", "Старт загрузки регистра Карбей ч2");
realm.executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
try {
URL url = new URL(url3);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.connect();
InputStream stream = connection.getInputStream();
realm.createAllFromJson(CarbayBrand.class, stream);
} catch (IOException e) {
e.printStackTrace();
}
}
});
Log.d("JsonGet", "Старт загрузки регистра Карбей ч3");
realm.executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
try {
URL url = new URL(url4);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.connect();
InputStream stream = connection.getInputStream();
realm.createAllFromJson(CarbayBrand.class, stream);
} catch (IOException e) {
e.printStackTrace();
}
}
});
}catch (Exception e){
e.printStackTrace();
}
finally {
realm.close();
//Log.d("JsonGet", "Realm closed! Realm instances="+Realm.getLocalInstanceCount(Realm.getDefaultConfiguration()));
}
Message msg;
msg = h.obtainMessage(LOADING_END, 0, 0);
h.sendMessage(msg);
}
synchronized void loadTyres(Context context, Handler h, int LOADING_END){
GlobalParams globalParams = new GlobalParams(context);
final String url1 = "http://" + globalParams.storage_url + "/get_tyres_v2.php";
Log.d("JsonGet", "Старт загрузки справочника шин");
try(Realm realm = Realm.getDefaultInstance()) {
realm.executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
realm.delete(Tyre.class);
}
});
// Insert multiple items using an InputStream
realm.executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
try {
URL url = new URL(url1);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.connect();
InputStream stream = connection.getInputStream();
realm.createAllFromJson(Tyre.class, stream);
} catch (IOException e) {
e.printStackTrace();
}
}
});
}catch (Exception e){
e.printStackTrace();
}
Message msg;
msg = h.obtainMessage(LOADING_END, 0, 0);
h.sendMessage(msg);
}
我的 logcat 错误消息
2019-07-12 15:05:09.347 11321-11362/com.lx2.crm E/REALM_JNI: jni: ThrowingException 5, mmap() failed: Out of memory size: 369098752 offset: 0 in /Users/Nabil/Dev/realm/master/realm-java/realm/realm-library/src/main/cpp/io_realm_internal_OsSharedRealm.cpp line 101, .
2019-07-12 15:05:09.350 11321-11362/com.lx2.crm E/REALM_JNI: Exception has been thrown: Unrecoverable error. mmap() failed: Out of memory size: 369098752 offset: 0 in /Users/Nabil/Dev/realm/master/realm-java/realm/realm-library/src/main/cpp/io_realm_internal_OsSharedRealm.cpp line 101
2019-07-12 15:05:09.352 11321-11362/com.lx2.crm E/AndroidRuntime: FATAL EXCEPTION: Thread-10
Process: com.lx2.crm, PID: 11321
io.realm.exceptions.RealmError: Unrecoverable error. mmap() failed: Out of memory size: 369098752 offset: 0 in /Users/Nabil/Dev/realm/master/realm-java/realm/realm-library/src/main/cpp/io_realm_internal_OsSharedRealm.cpp line 101
at io.realm.internal.OsSharedRealm.nativeGetSharedRealm(Native Method)
at io.realm.internal.OsSharedRealm.<init>(OsSharedRealm.java:184)
at io.realm.internal.OsSharedRealm.getInstance(OsSharedRealm.java:254)
at io.realm.internal.OsSharedRealm.getInstance(OsSharedRealm.java:244)
at io.realm.RealmCache.doCreateRealmOrGetFromCache(RealmCache.java:319)
at io.realm.RealmCache.createRealmOrGetFromCache(RealmCache.java:282)
at io.realm.Realm.getDefaultInstance(Realm.java:332)
at com.lx2.crm.LoginPageActivity.loadTyres(LoginPageActivity.java:1154)
at com.lx2.crm.LoginPageActivity$11.run(LoginPageActivity.java:1001)
at java.lang.Thread.run(Thread.java:764)
解决方案
它看起来像领域没有释放内存,直到异步任务没有完成。这就是为什么即使我尝试分割正在加载的文件时也会出现内存不足错误的原因。我的解决方案是划分加载文件并为每个文件制作异步任务。每个异步任务都由前一个任务中的回调开始。有点难看,但它的工作原理
推荐阅读
- php - Symfony - 按定义的状态渲染视图
- xcode - 在 IOS 12-Xamarin 上获取 CONNECTED WIFI 的 SSID(针对 iOS 13 更新)
- javascript - 在asp.net mvc 5中使用jQuery ajax的html表中没有填充Json数据
- react-native - 如何将 View 定位在 ScrollView 的底部?
- javascript - 无法在我的 HTML/JS 页面上获取背景图片
- javascript - 加载 JS 脚本,当用户按下浏览器上的后退按钮时
- java - java - 如何防止JSON响应中未使用的值在Java中使用Springfox返回为null?
- c# - 在 C# 控制台自托管 Web API 中实现 oAuth2.0 时出错
- python - TypeError:列表索引必须是整数或切片,而不是浮点数
- javascript - tsc 错误地将 .ts 文件编译成 .js