不可恢复的错误。 mremap():失败:io_realm_internal_SharedGroup.cpp第188行内存不足

时间:2015-10-28 07:07:35

标签: android realm

我已经将Realm作为我的数据库实现,并且在我的应用程序中,我在电话联系人上运行服务以检查我的电话簿中的任何更改。 该服务适用于3到4次更改,然后应用程序在我的logcat中崩溃并出现此错误。

无法恢复的错误。 mremap():失败:io_realm_internal_SharedGroup.cpp第188行内存不足

这是我的代码:

 public static void refreshingContactsDB()
{


        createCountryDetailsArrayModel();

        TelephonyManager tm = (TelephonyManager) ApplicationController.getInstance()
                .getSystemService(Context.TELEPHONY_SERVICE);
        String simCountryISO = tm.getSimCountryIso();

        for (int i = 0; i < countryDetailsList.size(); i++) {
            if (simCountryISO.equalsIgnoreCase(countryDetailsList.get(i)
                    .getCode())) {

                dialCodePrefix = countryDetailsList.get(i).getDial_code();

            }
        }


        AppPreferenceManager.getInstance().setContactUpdate(false);

        Logger.debug("Contact Update Refreshing Contact Started -->");

        Thread background = new Thread(new Runnable() {
            public void run() {

                Realm realmRefresh = Realm.getInstance(ApplicationController.getInstance());
                ContentResolver cr = ApplicationController.getInstance()
                        .getContentResolver();

                Cursor phones = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, PROJECTION, null, null, null);

                String duplicateName = "";
                String duplicatePhone = "";

                if (phones.getCount() > 0) {

                    final int nameIndex = phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME);
                    final int numberIndex = phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);

                    while (phones.moveToNext()) {
                        String name = phones.getString(nameIndex);
                        String phoneNo = phones.getString(numberIndex);

                        if (phoneNo != null && !phoneNo.isEmpty()) {

                            phoneNo = phoneNo.replace(" ", "");
                            phoneNo = phoneNo.replace("(", "");
                            phoneNo = phoneNo.replace(")", "");
                            phoneNo = phoneNo.replace("-", "");
                            phoneNo = phoneNo.replace("\u00a0", "");
                            phoneNo = phoneNo.replace("\u202c", "");
                            phoneNo = phoneNo.replace("\u2011", "");
                            phoneNo = phoneNo.replace("\u202a", "");
                            phoneNo = phoneNo.replace("*", "");
                            phoneNo = phoneNo.replace("#", "");

                            if (phoneNo.length() >= 5) {

                                if (name.equalsIgnoreCase(duplicateName) && phoneNo.equalsIgnoreCase(duplicatePhone)) {
                                    continue;
                                }

                                duplicateName = name;
                                duplicatePhone = phoneNo;

                                String formattedPhoneNumber;
                                formattedPhoneNumber = parseNumber(phoneNo);

                                //                                List<LocalContactDb> getContactsList = Select
                                //                                        .from(LocalContactDb.class)
                                //                                        .where(Condition.prop("PHONE").eq(
                                //                                                formattedPhoneNumber))
                                //                                        .list();
                                RealmResults<R_LocalContactDB> realmResults = realmRefresh.where(R_LocalContactDB.class).equalTo("phone", formattedPhoneNumber).findAll();
                                Logger.debug("Size: " + realmResults.size());
                                RealmResults<R_LocalContactDB> query = realmRefresh.where(R_LocalContactDB.class).findAll();
                                R_LocalContactDB rContacts = new R_LocalContactDB(null, null, false, 0);


                                if (realmResults.size() == 0) {
                                    realmRefresh.beginTransaction();
                                    R_LocalContactDB rCont = realmRefresh.copyToRealm(rContacts);
                                    rCont.setName(name);
                                    rCont.setPhone(formattedPhoneNumber);
                                    rCont.setStatus(0);
                                    rCont.setMatchedWithRecent(true);
                                    Logger.debug("New Size: " + query.size());
                                    realmRefresh.commitTransaction();

                                    Logger.debug("Contact Update " + name
                                            + " saved");
                                } else {
                                    realmRefresh.beginTransaction();
                                    if (!name.equalsIgnoreCase(realmResults.get(0).getName())) {
                                        realmResults.get(0).setName(name);
                                    }

                                    realmResults.get(0).setMatchedWithRecent(true);
                                    // realmResults.get(0);
                                    Logger.debug("New Size Else Condition: " + query.size());
                                    realmRefresh.commitTransaction();
                                    realmRefresh.close();


                                }

                            }


                        }

                    }
                    ContactsSyncService.contactUpdated= false ;

                    phones.close();


                }

                deleteExtraContacts();

                getNumbersFromDBAndUpdate();

            }

        });
        background.start();
    }

我已经阅读了这篇文章,但似乎无法从文档中完全理解它:

请注意,写入会相互阻塞,如果正在进行其他写入操作,则会阻止它们创建的线程。如果您正在从UI线程执行写操作,同时还从后台线程执行写操作,则会导致ANR错误。为了避免这种情况,首先在事务外部首先在内存中创建对象,并且只在事务中执行一个简单的Realm.copyToRealm(),这会将阻塞时间保持在最低限度。

1 个答案:

答案 0 :(得分:2)

您很可能内存不足,因为您在Realm.getInstance() - 主题中调用了parseContactstoContactsDB而没有再次关闭它。

因为每次调用该方法时都在创建一个新线程,所以每次有效地打开一个全新的Realm会占用非常重要的内存。

在退出线程之前调用realm.close()应该再次释放这些资源并防止内存不足。