Java Realm android应用程序崩溃:io.Realm.exceptions.RealmError:不可恢复的错误。mmap()失败:内存大小不足

Java Realm android应用程序崩溃:io.Realm.exceptions.RealmError:不可恢复的错误。mmap()失败:内存大小不足,java,android,database,realm,Java,Android,Database,Realm,我正在为我的下一个项目评估Realm数据库(Android)。我决定编写一个测试应用程序来插入100万个对象并检查Realm数据库的性能。测试应用程序是一个简单的android应用程序。 用户可以指定要创建的特定模型类的随机对象数量,这些对象是在后台的IntentService中创建的。创建对象时,“活动”将显示域中对象的总数 用于创建随机对象的IntentService package example.com.realmcrashapplication; import android.app

我正在为我的下一个项目评估Realm数据库(Android)。我决定编写一个测试应用程序来插入100万个对象并检查Realm数据库的性能。测试应用程序是一个简单的android应用程序。 用户可以指定要创建的特定模型类的随机对象数量,这些对象是在后台的IntentService中创建的。创建对象时,“活动”将显示域中对象的总数

用于创建随机对象的IntentService

package example.com.realmcrashapplication;

import android.app.IntentService;
import android.content.Intent;
import android.os.Bundle;
import io.realm.Realm;

public class BackendService extends IntentService {

public static final String TASK_DETAILS = "taskDetails";
public static final String INSERTION_COUNT = "insertionCount";    
private static final int insertsPerTransaction = 1000;
private int remainingInsertions = 0;

public BackendService() {
    super(BackendService.class.getName());
}

@Override
protected void onHandleIntent(Intent intent) {
    Bundle args = intent.getBundleExtra(TASK_DETAILS);
    if(args != null) {
        if(args.containsKey(INSERTION_COUNT)){
            final int count = args.getInt(INSERTION_COUNT);
            if(count>0){
                remainingInsertions = count;
                while(remainingInsertions>0){
                    final int c;
                    if(remainingInsertions>insertsPerTransaction){
                        c=insertsPerTransaction;
                    }else{
                        c=remainingInsertions;
                    }
                    Realm realm = Realm.getDefaultInstance();
                    final Person p = Person.getRandomPerson();
                    realm.executeTransaction(new Realm.Transaction() {
                        @Override
                        public void execute(Realm realm) {
                            for(int i=0;i<c;++i) {
                                realm.copyToRealm(p);
                            }
                        }
                    });
                    realm.close();
                    remainingInsertions-=c;
                }
            }

        }
    }
 }

}
我曾尝试将每次交易的插入次数从1000次减少到10次,但结果是一样的。我的手机有足够的空间。所以我想这不是关于存储的。100K插入后的文件大小跨越600MB(145K对象后为704MB)

领域库1.0.1 Android Java

测试日期:三星Galaxy Note 2 Android 4.4.2 API 19

模型类

package example.com.realmcrashapplication;

import java.util.Date;
import io.realm.RealmList;
import io.realm.RealmObject;

public class Person extends RealmObject{
private int field1;
private String field2;
private Date field3;
private String field4;
private Date field5;
private String field6;
private String field7;
private int field8;
private double field9;
private String field10;
private int field11;
private int field12;
private double field13;
private double field14;
private int field15;
private String field16;
private double field17;
private boolean field18;
private String field19;
private double field20;
private boolean field21;
private boolean field22;
private int field23;
private ExtraInfo1 field24;
private ExtraInfo1 field25;
private ExtraInfo1 field26;
private ExtraInfo1 field27;
private ExtraInfo1 field28;
private RealmList<ExtraInfo2> field29;
private Integer field30;
private String field31;
private String field32;
private String field33;
private String field34;
private String field35;
private String field36;
private Address field37;
private boolean field38;
private Date field39;
private int field40;
private int field41;
private double field42;
private double field43;
private String field44;
private String field45;
private String field46;
private Address field47;
private int field48;
private String field49;
private Date field50;
private String field51;
private boolean field52;
private RealmList<ExtraInfo3> field53;
private double field54;
private double field55;
private double field56;
private RealmList<Person> family;

public void setField1(int field1) {
    this.field1 = field1;
}
public void setField2(String field2) {
    this.field2 = field2;
}
public void setField3(Date field3) {
    this.field3 = field3;
}
public void setField4(String field4) {
    this.field4 = field4;
}
public void setField5(Date field5) {
    this.field5 = field5;
}
public void setField6(String field6) {
    this.field6 = field6;
}
public void setField7(String field7) {
    this.field7 = field7;
}
public void setField8(int field8) {
    this.field8 = field8;
}
public void setField9(double field9) {
    this.field9 = field9;
}
public void setField10(String field10) {
    this.field10 = field10;
}
public void setField11(int field11) {
    this.field11 = field11;
}
public void setField12(int field12) {
    this.field12 = field12;
}
public void setField13(double field13) {
    this.field13 = field13;
}
public void setField14(double field14) {
    this.field14 = field14;
}
public void setField15(int field15) {
    this.field15 = field15;
}
public void setField16(String field16) {
    this.field16 = field16;
}
public void setField17(double field17) {
    this.field17 = field17;
}
public void setField18(boolean field18) {
    this.field18 = field18;
}
public void setField19(String field19) {
    this.field19 = field19;
}
public void setField20(double field20) {
    this.field20 = field20;
}
public void setField21(boolean field21) {
    this.field21 = field21;
}
public void setField22(boolean field22) {
    this.field22 = field22;
}
public void setField23(int field23) {
    this.field23 = field23;
}
public void setField24(ExtraInfo1 field24) {
    this.field24 = field24;
}
public void setField25(ExtraInfo1 field25) {
    this.field25 = field25;
}
public void setField26(ExtraInfo1 field26) {
    this.field26 = field26;
}
public void setField27(ExtraInfo1 field27) {
    this.field27 = field27;
}
public void setField28(ExtraInfo1 field28) {
    this.field28 = field28;
}
public void setField29(RealmList<ExtraInfo2> field29) {
    this.field29 = field29;
}
public void setField30(Integer field30) {
    this.field30 = field30;
}
public void setField31(String field31) {
    this.field31 = field31;
}
public void setField32(String field32) {
    this.field32 = field32;
}
public void setField33(String field33) {
    this.field33 = field33;
}
public void setField34(String field34) {
    this.field34 = field34;
}
public void setField35(String field35) {
    this.field35 = field35;
}
public void setField36(String field36) {
    this.field36 = field36;
}
public void setField37(Address field37) {
    this.field37 = field37;
}
public void setField38(boolean field38) {
    this.field38 = field38;
}
public void setField39(Date field39) {
    this.field39 = field39;
}
public void setField40(int field40) {
    this.field40 = field40;
}
public void setField41(int field41) {
    this.field41 = field41;
}
public void setField42(double field42) {
    this.field42 = field42;
}
public void setField43(double field43) {
    this.field43 = field43;
}
public void setField44(String field44) {
    this.field44 = field44;
}
public void setField45(String field45) {
    this.field45 = field45;
}
public void setField46(String field46) {
    this.field46 = field46;
}
public void setField47(Address field47) {
    this.field47 = field47;
}
public void setField48(int field48) {
    this.field48 = field48;
}
public void setField49(String field49) {
    this.field49 = field49;
}
public void setField50(Date field50) {
    this.field50 = field50;
}
public void setField51(String field51) {
    this.field51 = field51;
}
public void setField52(boolean field52) {
    this.field52 = field52;
}
public void setField53(RealmList<ExtraInfo3> field53) {
    this.field53 = field53;
}
public void setField54(double field54) {
    this.field54 = field54;
}
public void setField55(double field55) {
    this.field55 = field55;
}
public void setField56(double field56) {
    this.field56 = field56;
}
public void setFamily(RealmList<Person> family) {
    this.family = family;
}
public static Person getRandomPerson(){
    Person p = new Person();
    p.setField1(9);
    p.setField2(HelperClass.getRandomString(15));
    p.setField3(HelperClass.getRandomDate());
    p.setField4(HelperClass.getRandomString(15));
    p.setField5(HelperClass.getRandomDate());
    p.setField6(HelperClass.getRandomString(24));
    p.setField7(HelperClass.getRandomString(100));
    p.setField8(9);
    p.setField9(0.567);
    p.setField10(HelperClass.getRandomString(3));
    p.setField11(9);
    p.setField12(1);
    p.setField13(45.00);
    p.setField14(0);
    p.setField15(1);
    p.setField16(HelperClass.getRandomString(15));
    p.setField17(5);
    p.setField18(true);
    p.setField19(HelperClass.getRandomString(15));
    p.setField20(5);
    p.setField21(true);
    p.setField22(true);
    p.setField23(5);
    p.setField24(ExtraInfo1.getRandomExtraInfo1());
    p.setField25(ExtraInfo1.getRandomExtraInfo1());
    p.setField26(ExtraInfo1.getRandomExtraInfo1());
    p.setField27(ExtraInfo1.getRandomExtraInfo1());
    p.setField28(ExtraInfo1.getRandomExtraInfo1());

    RealmList<ExtraInfo2> extraInfo2Items = new RealmList<>();
    for (int i = 0; i < 10; ++i) {
        ExtraInfo2 extraInfo2 = ExtraInfo2.getRandomExtraInfo2();
        extraInfo2Items.add(extraInfo2);
    }
    p.setField29(extraInfo2Items);
    p.setField30(1);
    p.setField31(HelperClass.getRandomString(24));
    p.setField32(HelperClass.getRandomString(24));
    p.setField33(HelperClass.getRandomString(10));
    p.setField34(HelperClass.getRandomString(10));
    p.setField35(HelperClass.getRandomString(128));
    p.setField36(HelperClass.getRandomString(10));
    p.setField37(Address.getRandomAddress());
    p.setField38(true);
    p.setField39(HelperClass.getRandomDate());
    p.setField40(1);
    p.setField41(1);
    p.setField42(10);
    p.setField43(0.00);
    p.setField44(HelperClass.getRandomString(24));
    p.setField45(HelperClass.getRandomString(100));
    p.setField46(HelperClass.getRandomString(30));
    p.setField47(Address.getRandomAddress());
    p.setField48(30);
    p.setField49(HelperClass.getRandomString(30));
    p.setField50(HelperClass.getRandomDate());
    p.setField51(HelperClass.getRandomString(100));
    p.setField52(true);

    RealmList<ExtraInfo3> extraInfo3List = new RealmList<>();
    for (int i = 0; i < 5; ++i) {
        ExtraInfo3 extraInfo3 = ExtraInfo3.getRandomExtraInfo3();
        extraInfo3List.add(extraInfo3);
    }
    p.setField53(extraInfo3List);
    p.setField54(100);
    p.setField55(100);
    p.setField56(0);
    return p;
}
}
public class MyApplication extends Application {
    public static String location = "";
    @Override
    public void onCreate() {
        super.onCreate();
        File dir = new File("/sdcard/realm2");
        if(!dir.exists()){
            dir.mkdirs();
        }
        location = dir.getAbsolutePath();
        RealmConfiguration realmConfiguration = new RealmConfiguration.Builder(dir).
                                                    deleteRealmIfMigrationNeeded().
                                                    build();
        Realm.setDefaultConfiguration(realmConfiguration);
    }
}
ExtraInfo1

package example.com.realmcrashapplication;

import io.realm.RealmObject;

public class ExtraInfo1 extends RealmObject {
private String field1;
private boolean field2;
private int field3;
private int field4;
private double field5;
private double field6;
private int field7;
private boolean field8;
private String field9;
private double field10;
private String field11;
private double field12;
private boolean field13;

public void setField1(String field1) {
    this.field1 = field1;
}
public void setField2(boolean field2) {
    this.field2 = field2;
}
public void setField3(int field3) {
    this.field3 = field3;
}
public void setField4(int field4) {
    this.field4 = field4;
}
public void setField5(double field5) {
    this.field5 = field5;
}
public void setField6(double field6) {
    this.field6 = field6;
}
public void setField7(int field7) {
    this.field7 = field7;
}
public void setField8(boolean field8) {
    this.field8 = field8;
}
public void setField9(String field9) {
    this.field9 = field9;
}
public void setField10(double field10) {
    this.field10 = field10;
}
public void setField11(String field11) {
    this.field11 = field11;
}
public void setField12(double field12) {
    this.field12 = field12;
}
public void setField13(boolean field13) {
    this.field13 = field13;
}

public static ExtraInfo1 getRandomExtraInfo1(){
    ExtraInfo1 info = new ExtraInfo1();
    info.setField1(HelperClass.getRandomString(10));
    info.setField2(true);
    info.setField3(1);
    info.setField4(1);
    info.setField5(0);
    info.setField6(0);
    info.setField7(1);
    info.setField8(true);
    info.setField9(HelperClass.getRandomString(15));
    info.setField10(5);
    info.setField11(HelperClass.getRandomString(15));
    info.setField12(5);
    info.setField13(true);
    return info;
}
}
ExtraInfo2

package example.com.realmcrashapplication;

import io.realm.RealmObject;

public class ExtraInfo2 extends RealmObject {
private int field1;
private String field2;
private double field3;
private boolean field4;
private double field5;
private String field6;
private double field7;
private int field8;
private double field9;
private double field10;
private String field11;
private boolean field12;
private String field13;
private double field14;
private String field15;
private double field16;
private boolean field17;

public void setField1(int field1) {
    this.field1 = field1;
}
public void setField2(String field2) {
    this.field2 = field2;
}

public void setField3(double field3) {
    this.field3 = field3;
}
public void setField4(boolean field4) {
    this.field4 = field4;
}
public void setField5(double field5) {
    this.field5 = field5;
}
public void setField6(String field6) {
    this.field6 = field6;
}
public void setField7(double field7) {
    this.field7 = field7;
}
public void setField8(int field8) {
    this.field8 = field8;
}
public void setField9(double field9) {
    this.field9 = field9;
}

public void setField10(double field10) {
    this.field10 = field10;
}
public void setField11(String field11) {
    this.field11 = field11;
}
public void setField12(boolean field12) {
    this.field12 = field12;
}
public void setField13(String field13) {
    this.field13 = field13;
}
public void setField14(double field14) {
    this.field14 = field14;
}
public void setField15(String field15) {
    this.field15 = field15;
}
public void setField16(double field16) {
    this.field16 = field16;
}
public void setField17(boolean field17) {
    this.field17 = field17;
}

public static ExtraInfo2 getRandomExtraInfo2(){
    ExtraInfo2 extraInfo2 = new ExtraInfo2();
    extraInfo2.setField1(1);
    extraInfo2.setField2(HelperClass.getRandomString(15));
    extraInfo2.setField3(18.0);
    extraInfo2.setField4(true);
    extraInfo2.setField5(9.0);
    extraInfo2.setField6("value");
    extraInfo2.setField7(1.0);
    extraInfo2.setField8(1);
    extraInfo2.setField9(0.0);
    extraInfo2.setField10(0.0);
    extraInfo2.setField11(HelperClass.getRandomString(100));
    extraInfo2.setField12(true);
    extraInfo2.setField13(HelperClass.getRandomString(15));
    extraInfo2.setField14(5);
    extraInfo2.setField15(HelperClass.getRandomString(15));
    extraInfo2.setField16(5);
    extraInfo2.setField17(true);
    return extraInfo2;
}
}
ExtraInfo3

package example.com.realmcrashapplication;

import java.util.Date;
import io.realm.RealmObject;

public class ExtraInfo3 extends RealmObject {
private Date field1;
private int field2;
private String field3;
private double field4;
private String field5;
private String field6;

public void setField1(Date field1) {
    this.field1 = field1;
}
public void setField2(int field2) {
    this.field2 = field2;
}
public void setField3(String field3) {
    this.field3 = field3;
}
public void setField4(double field4) {
    this.field4 = field4;
}
public void setField5(String field5) {
    this.field5 = field5;
}
public void setField6(String field6) {
    this.field6 = field6;
}

public static ExtraInfo3 getRandomExtraInfo3(){
    ExtraInfo3 extraInfo3 = new ExtraInfo3();
    extraInfo3.setField1(HelperClass.getRandomDate());
    extraInfo3.setField2(1);
    extraInfo3.setField3(HelperClass.getRandomString(10));
    extraInfo3.setField4(10.00);
    extraInfo3.setField5(HelperClass.getRandomString(10));
    extraInfo3.setField6(HelperClass.getRandomString(24));
    return extraInfo3;
}
}
main活动

package example.com.realmcrashapplication;

import android.content.Intent;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.Window;
import android.widget.TextView;
import io.realm.Realm;
import io.realm.RealmChangeListener;
import io.realm.RealmResults;
import io.realm.Sort;

public class MainActivity extends AppCompatActivity {
    private Realm realm;
    private RealmResults<Person> persons;
    private RealmChangeListener personsChangeListener;
    private TextView personCountTextView;
    private Intent backgroundIntent;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        personCountTextView = (TextView)findViewById(R.id.personCountText);
        TextView locationText = (TextView)findViewById(R.id.locationText);
        locationText.setText(MyApplication.location);
        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                InsertPersonsDialogFragment newFragment = new InsertPersonsDialogFragment();
                newFragment.setClickListener(new InsertPersonsDialogFragment.ClickListener() {
                    @Override
                    public void onInsertItems(int count) {
                        insertPersons(count);
                    }
                });
                newFragment.show(getSupportFragmentManager(), "insertPersonsDialog");
            }
        });
        backgroundIntent = new Intent(MainActivity.this,BackendService.class);
    }
    @Override
    public void onStart() {
        super.onStart();
        realm = Realm.getDefaultInstance();
        persons = realm.where(Person.class).findAllSortedAsync("field3", Sort.DESCENDING);
        personsChangeListener = new RealmChangeListener<RealmResults<Person>>() {
            @Override
            public void onChange(final RealmResults<Person> personsList) {
                MainActivity.this.runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        if(personCountTextView!=null) {
                            String size = Integer.toString(personsList.size());
                            personCountTextView.setText("Number of persons : "+size);
                        }

                    }
                });
            }
        };
        persons.addChangeListener(personsChangeListener);
    }
    @Override
    public void onStop() {
        super.onStop();
        if(personsChangeListener!=null){
            realm.removeChangeListener(personsChangeListener);
        }
        realm.close();
    }
    private void insertPersons(final int count) {
        Bundle args = new Bundle();
        args.putInt(BackendService.INSERTION_COUNT, count);
        backgroundIntent.putExtra(BackendService.TASK_DETAILS, args);
        startService(backgroundIntent);
    }
}

三星Galaxy Note 2是32位设备,在32位Android上,
mmap()
通常限制在300-600 MB。@geisshirt如果是这种情况,我必须在多个领域文件之间分割数据。我说的对吗?在Realm,我们完全意识到了这个限制,并且我们目前正在努力改变
mmap()
的使用模式。“我不能保证修复程序什么时候会出来。”geisshirt感谢您的帮助info@geisshirt,请务必解决此问题。这对我们来说确实是个大问题。
package example.com.realmcrashapplication;

import android.content.Intent;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.Window;
import android.widget.TextView;
import io.realm.Realm;
import io.realm.RealmChangeListener;
import io.realm.RealmResults;
import io.realm.Sort;

public class MainActivity extends AppCompatActivity {
    private Realm realm;
    private RealmResults<Person> persons;
    private RealmChangeListener personsChangeListener;
    private TextView personCountTextView;
    private Intent backgroundIntent;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        personCountTextView = (TextView)findViewById(R.id.personCountText);
        TextView locationText = (TextView)findViewById(R.id.locationText);
        locationText.setText(MyApplication.location);
        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                InsertPersonsDialogFragment newFragment = new InsertPersonsDialogFragment();
                newFragment.setClickListener(new InsertPersonsDialogFragment.ClickListener() {
                    @Override
                    public void onInsertItems(int count) {
                        insertPersons(count);
                    }
                });
                newFragment.show(getSupportFragmentManager(), "insertPersonsDialog");
            }
        });
        backgroundIntent = new Intent(MainActivity.this,BackendService.class);
    }
    @Override
    public void onStart() {
        super.onStart();
        realm = Realm.getDefaultInstance();
        persons = realm.where(Person.class).findAllSortedAsync("field3", Sort.DESCENDING);
        personsChangeListener = new RealmChangeListener<RealmResults<Person>>() {
            @Override
            public void onChange(final RealmResults<Person> personsList) {
                MainActivity.this.runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        if(personCountTextView!=null) {
                            String size = Integer.toString(personsList.size());
                            personCountTextView.setText("Number of persons : "+size);
                        }

                    }
                });
            }
        };
        persons.addChangeListener(personsChangeListener);
    }
    @Override
    public void onStop() {
        super.onStop();
        if(personsChangeListener!=null){
            realm.removeChangeListener(personsChangeListener);
        }
        realm.close();
    }
    private void insertPersons(final int count) {
        Bundle args = new Bundle();
        args.putInt(BackendService.INSERTION_COUNT, count);
        backgroundIntent.putExtra(BackendService.TASK_DETAILS, args);
        startService(backgroundIntent);
    }
}
public class MyApplication extends Application {
    public static String location = "";
    @Override
    public void onCreate() {
        super.onCreate();
        File dir = new File("/sdcard/realm2");
        if(!dir.exists()){
            dir.mkdirs();
        }
        location = dir.getAbsolutePath();
        RealmConfiguration realmConfiguration = new RealmConfiguration.Builder(dir).
                                                    deleteRealmIfMigrationNeeded().
                                                    build();
        Realm.setDefaultConfiguration(realmConfiguration);
    }
}