我试图将大型json文件下载到领域数据库中。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)发布于 2019-08-20 10:24:17
它看起来像没有释放内存的领域,直到异步任务还没有完成。这就是为什么当我试图分割文件im加载时,内存出现错误的原因。我的解决方案是划分加载文件并为每个文件创建异步任务。在以前的任务中,每个异步任务都通过回调启动。有点丑,但很管用
发布于 2019-07-13 22:18:41
Ilshat,欢迎来到StackOverflow。
loadTyres()的一个不同之处在于它使用的是一条具有资源的试用语句:
try(Realm realm = Realm.getDefaultInstance()) { 而loadCarbay()不是:
Realm realm = Realm.getDefaultInstance();
try{ 可能领域不兼容使用资源的尝试语句。尝试让loadCarbay()在try块之前获取领域实例,以查看这是否解决了问题。这只是猜测而已。
如果这样做,请记住使用realm.close();添加一个最终块
发布于 2019-07-18 13:58:02
我发现为什么每当我得到实例时领域崩溃--在我的设备中内存不足。我在另一个内存很大的设备上安装了我的应用程序,一切都很好。
https://stackoverflow.com/questions/57006800
复制相似问题