-->

pthread_create failed: couldn't allocate 10649

2019-08-25 10:15发布

问题:

I have two fragments where inside both of these fragments, it will execute codes that utilize sqlbrite. While the app won't crash in normal usage, but the problem is, if I load these 2 fragments back-and-forth multiple times in a short period, the app will crash with this error.

E/CursorWindow: Could not allocate CursorWindow '/data/data/com.imincode.meniti/databases/meniti' of size 2097152 due to error -12.
E/CursorWindow: Could not allocate CursorWindow '/data/data/com.imincode.meniti/databases/meniti' of size 2097152 due to error -12.
E/CursorWindow: Could not allocate CursorWindow '/data/data/com.imincode.meniti/databases/meniti' of size 2097152 due to error -12.
W/libc: pthread_create failed: couldn't allocate 1064960-byte stack: Out of memory
W/libc: pthread_create failed: couldn't allocate 1064960-byte stack: Out of memory
W/System.err: android.database.CursorWindowAllocationException: Cursor window allocation of 2048 kb failed. 
W/System.err: android.database.CursorWindowAllocationException: Cursor window allocation of 2048 kb failed. 
W/System.err: android.database.CursorWindowAllocationException: Cursor window allocation of 2048 kb failed. 
E/CursorWindow: Could not allocate CursorWindow '/data/data/com.imincode.meniti/databases/meniti' of size 2097152 due to error -12.
W/System.err: android.database.CursorWindowAllocationException: Cursor window allocation of 2048 kb failed. 
E/CursorWindow: Could not allocate CursorWindow '/data/data/com.imincode.meniti/databases/meniti' of size 2097152 due to error -12.
W/System.err: android.database.CursorWindowAllocationException: Cursor window allocation of 2048 kb failed. 
E/art: Throwing OutOfMemoryError "pthread_create (1040KB stack) failed: Try again"
E/art: Throwing OutOfMemoryError "pthread_create (1040KB stack) failed: Try again"
W/System.err:     at    at android.database.CursorWindow.<init>(CursorWindow.java:108)
W/System.err:     at    at android.database.CursorWindow.<init>(CursorWindow.java:108)
W/System.err:     at    at android.database.AbstractWindowedCursor.clearOrCreateWindow(AbstractWindowedCursor.java:198)
W/System.err:     at android.database.CursorWindow.<init>(CursorWindow.java:108)
W/System.err:     at    at android.database.AbstractWindowedCursor.clearOrCreateWindow(AbstractWindowedCursor.java:198)
W/System.err:     at android.database.CursorWindow.<init>(CursorWindow.java:108)
W/System.err:     at android.database.CursorWindow.<init>(CursorWindow.java:108)
W/System.err:     at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:139)
W/System.err:     at android.database.AbstractWindowedCursor.clearOrCreateWindow(AbstractWindowedCursor.java:198)
W/System.err:     at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:139)
W/System.err:     at android.database.sqlite.SQLiteCursor.getCount(SQLiteCursor.java:133)
W/System.err:     at com.imincode.meniti.db.DbHelper$6.call(DbHelper.java:438)
W/System.err:     at com.imincode.meniti.db.DbHelper$6.call(DbHelper.java:431)
W/System.err:     at rx.internal.operators.OnSubscribeMap$MapSubscriber.onNext(OnSubscribeMap.java:69)
W/System.err:     at rx.observers.Subscribers$5.onNext(Subscribers.java:235)
W/System.err:     at rx.internal.operators.OperatorOnBackpressureLatest$LatestEmitter.emit(OperatorOnBackpressureLatest.java:165)
W/System.err:     at rx.internal.operators.OperatorOnBackpressureLatest$LatestEmitter.onNext(OperatorOnBackpressureLatest.java:131)
W/System.err:     at rx.internal.operators.OperatorOnBackpressureLatest$LatestSubscriber.onNext(OperatorOnBackpressureLatest.java:211)
W/System.err:     at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber.call(OperatorObserveOn.java:224)
W/System.err:     at rx.internal.schedulers.CachedThreadScheduler$EventLoopWorker$1.call(CachedThreadScheduler.java:230)
W/System.err: android.database.AbstractWindowedCursor.clearOrCreateWindow(AbstractWindowedCursor.java:198)
W/System.err:     at    at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:139)
W/System.err:     at android.database.sqlite.SQLiteCursor.getCount(SQLiteCursor.java:133)
W/System.err:     at com.imincode.meniti.db.DbHelper$4.call(DbHelper.java:368)
W/System.err:     at com.imincode.meniti.db.DbHelper$4.call(DbHelper.java:361)
W/System.err:     at rx.internal.operators.OnSubscribeMap$MapSubscriber.onNext(OnSubscribeMap.java:69)
W/System.err:     at rx.observers.Subscribers$5.onNext(Subscribers.java:235)
W/System.err:     at rx.internal.operators.OperatorOnBackpressureLatest$LatestEmitter.emit(OperatorOnBackpressureLatest.java:165)
W/System.err:     at rx.internal.operators.OperatorOnBackpressureLatest$LatestEmitter.onNext(OperatorOnBackpressureLatest.java:131)
W/System.err:     at rx.internal.operators.OperatorOnBackpressureLatest$LatestSubscriber.onNext(OperatorOnBackpressureLatest.java:211)
W/System.err:     at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber.call(OperatorObserveOn.java:224)
W/System.err:     at android.database.AbstractWindowedCursor.clearOrCreateWindow(AbstractWindowedCursor.java:198)
W/System.err:     at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:139)
W/System.err:     at android.database.sqlite.SQLiteCursor.getCount(SQLiteCursor.java:133)
W/System.err:     at android.database.sqlite.SQLiteCursor.getCount(SQLiteCursor.java:133)
W/System.err:     at com.imincode.meniti.db.DbHelper$6.call(DbHelper.java:438)
W/System.err:     at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55)
W/System.err:     at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422)
W/System.err:     at com.imincode.meniti.db.DbHelper$6.call(DbHelper.java:431)
W/System.err:     at rx.internal.operators.OnSubscribeMap$MapSubscriber.onNext(OnSubscribeMap.java:69)
W/System.err:     at rx.observers.Subscribers$5.onNext(Subscribers.java:235)
W/System.err:     at rx.internal.operators.OperatorOnBackpressureLatest$LatestEmitter.emit(OperatorOnBackpressureLatest.java:165)
W/System.err: android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:139)
W/System.err:     at android.database.sqlite.SQLiteCursor.getCount(SQLiteCursor.java:133)
W/System.err:     at com.imincode.meniti.db.DbHelper$4.call(DbHelper.java:368)
W/System.err:     at com.imincode.meniti.db.DbHelper$4.call(DbHelper.java:361)
W/System.err:     at rx.internal.operators.OnSubscribeMap$MapSubscriber.onNext(OnSubscribeMap.java:69)
W/System.err:     at rx.observers.Subscribers$5.onNext(Subscribers.java:235)
W/System.err:     at rx.internal.operators.OperatorOnBackpressureLatest$LatestEmitter.emit(OperatorOnBackpressureLatest.java:165)
W/System.err:     at rx.internal.operators.OperatorOnBackpressureLatest$LatestEmitter.onNext(OperatorOnBackpressureLatest.java:131)
W/System.err:     at rx.internal.operators.OperatorOnBackpressureLatest$LatestSubscriber.onNext(OperatorOnBackpressureLatest.java:211)
W/System.err:     at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber.call(OperatorObserveOn.java:224)
W/System.err:     at rx.internal.schedulers.CachedThreadScheduler$EventLoopWorker$1.call(CachedThreadScheduler.java:230)
W/System.err:     at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55)
W/System.err:     at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422)
W/System.err:     at java.util.concurrent.FutureTask.run(FutureTask.java:237)
W/System.err:     at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:152)
W/System.err:     at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:265)
W/System.err:     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
W/System.err:     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
W/System.err:     at java.lang.Thread.run(Thread.java:818)
W/System.err:     at rx.internal.operators.OperatorOnBackpressureLatest$LatestEmitter.onNext(OperatorOnBackpressureLatest.java:131)
W/System.err:     at rx.internal.operators.OperatorOnBackpressureLatest$LatestSubscriber.onNext(OperatorOnBackpressureLatest.java:211)
W/System.err:     at java.util.concurrent.FutureTask.run(FutureTask.java:237)
W/System.err:     at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:152)
W/System.err:     at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:265)
W/System.err:     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
W/System.err:     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
W/System.err:     at java.lang.Thread.run(Thread.java:818)com.imincode.meniti.db.DbHelper$4.call(DbHelper.java:368)
W/System.err:     at com.imincode.meniti.db.DbHelper$4.call(DbHelper.java:361)
W/System.err:     at rx.internal.operators.OnSubscribeMap$MapSubscriber.onNext(OnSubscribeMap.java:69)
W/System.err:     at rx.observers.Subscribers$5.onNext(Subscribers.java:235)
W/System.err:     at rx.internal.operators.OperatorOnBackpressureLatest$LatestEmitter.emit(OperatorOnBackpressureLatest.java:165)
W/System.err: rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber.call(OperatorObserveOn.java:224)
W/System.err:     at rx.internal.schedulers.CachedThreadScheduler$EventLoopWorker$1.call(CachedThreadScheduler.java:230)
W/System.err:     at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55)
W/System.err:     at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422)
W/System.err:     at java.util.concurrent.FutureTask.run(FutureTask.java:237)
W/System.err:     at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:152)
W/System.err:     at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:265)
W/System.err:     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
W/System.err:     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
W/System.err:     at java.lang.Thread.run(Thread.java:818)
W/System.err:     at rx.internal.operators.OperatorOnBackpressureLatest$LatestEmitter.onNext(OperatorOnBackpressureLatest.java:131)
W/System.err:     at rx.internal.operators.OperatorOnBackpressureLatest$LatestSubscriber.onNext(OperatorOnBackpressureLatest.java:211)
W/System.err:     at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber.call(OperatorObserveOn.java:224)
W/System.err:     at rx.internal.schedulers.CachedThreadScheduler$EventLoopWorker$1.call(CachedThreadScheduler.java:230)
W/System.err:     at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55)
W/System.err: rx.internal.schedulers.CachedThreadScheduler$EventLoopWorker$1.call(CachedThreadScheduler.java:230)
W/System.err:     at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55)
W/System.err:     at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422)
W/System.err:     at java.util.concurrent.FutureTask.run(FutureTask.java:237)
W/System.err:     at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:152)
W/System.err:     at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:265)
W/System.err:     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
W/System.err:     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
W/System.err:     at java.lang.Thread.run(Thread.java:818)
W/System.err:     at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422)
W/System.err:     at java.util.concurrent.FutureTask.run(FutureTask.java:237)
W/System.err:     at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:152)
W/System.err:     at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:265)
W/System.err:     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
W/System.err:     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
W/System.err:     at java.lang.Thread.run(Thread.java:818)
W/libc: pthread_create failed: couldn't allocate 1064960-byte stack: Out of memory
E/art: Throwing OutOfMemoryError "pthread_create (1040KB stack) failed: Try again"
W/libc: pthread_create failed: couldn't allocate 1064960-byte stack: Out of memory
E/art: Throwing OutOfMemoryError "pthread_create (1040KB stack) failed: Try again"

One of the fragment has about 50 Observable which are then combined using Observable.combineLatest. Here's the code snippet for the fragment (the other fragment have a similar code). Below is basically the simplified version of my code.

public class MenuSummary extends Fragment{

private DbHelper dbHelper;
private Observable<?> incomeFromParentJar, getIncomeNecessities, getIncomeSavings, getIncomeEntertainment, getIncomeInvestment, getIncomeEducation, getIncomeCharity;
private Observable<?> getExpensesNecessities, getExpensesSavings, getExpensesEntertainment, getExpensesInvestment, getExpensesEducation, getExpensesCharity;
private Observable<?> getTotalUnpaidMonthlyRecurringExpensesNecessities, getTotalUnpaidMonthlyRecurringExpensesSavings;
private Observable imin;
private Subscription s;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    dbHelper = new DbHelper(getContext());
}

@Override
public void onPause(){
    super.onPause();
    dbHelper.close();
    s.unsubscribe();
}

@Override
public void onResume(){
    super.onResume();
    displaySummary(selectedYear,selectedMonth);
}

@Override
public void onStop() {
    super.onStop();
}

@Override
public void onActivityCreated(Bundle savedInstanceState){
    super.onActivityCreated(savedInstanceState);
}

private void displaySummary(final int selectedYear, final int selectedMonth){

    incomeFromParentJar = dbHelper.getParentJarIncomeUpTo(selectedYear,selectedMonth);
    getIncomeNecessities = dbHelper.getIndividualJarIncomeUpTo(selectedYear,selectedMonth,MySQLiteHelper.JAR_NECESSITIES);
    getIncomeSavings = dbHelper.getIndividualJarIncomeUpTo(selectedYear,selectedMonth,MySQLiteHelper.JAR_SAVINGS);
    getIncomeEntertainment = dbHelper.getIndividualJarIncomeUpTo(selectedYear,selectedMonth,MySQLiteHelper.JAR_ENTERTAINMENT);
    getIncomeInvestment = dbHelper.getIndividualJarIncomeUpTo(selectedYear,selectedMonth,MySQLiteHelper.JAR_INVESTMENT);
    getIncomeEducation = dbHelper.getIndividualJarIncomeUpTo(selectedYear,selectedMonth,MySQLiteHelper.JAR_EDUCATION);
    getIncomeCharity = dbHelper.getIndividualJarIncomeUpTo(selectedYear,selectedMonth,MySQLiteHelper.JAR_CHARITY);

    getExpensesNecessities = dbHelper.getJarExpensesUpTo(selectedYear,selectedMonth,MySQLiteHelper.JAR_NECESSITIES);
    getExpensesSavings = dbHelper.getJarExpensesUpTo(selectedYear,selectedMonth,MySQLiteHelper.JAR_SAVINGS);
    getExpensesEntertainment = dbHelper.getJarExpensesUpTo(selectedYear,selectedMonth,MySQLiteHelper.JAR_ENTERTAINMENT);
    getExpensesInvestment = dbHelper.getJarExpensesUpTo(selectedYear,selectedMonth,MySQLiteHelper.JAR_INVESTMENT);
    getExpensesEducation = dbHelper.getJarExpensesUpTo(selectedYear,selectedMonth,MySQLiteHelper.JAR_EDUCATION);
    getExpensesCharity = dbHelper.getJarExpensesUpTo(selectedYear,selectedMonth,MySQLiteHelper.JAR_CHARITY);

    List<Observable<?>> myObservables = Arrays.asList(incomeFromParentJar,getIncomeNecessities,getIncomeSavings,getIncomeEntertainment, getIncomeInvestment,getIncomeEducation,getIncomeCharity,getExpensesNecessities,getExpensesSavings,getExpensesEntertainment,getExpensesInvestment, getExpensesEducation,getExpensesCharity);
    imin = Observable.combineLatest(myObservables, new FuncN<List<BigDecimal>>() {
        @Override
        public List<BigDecimal> call(Object... args) {
            BigDecimal incomeTotal, incomeNecessities, incomeSavings, incomeEntertainment;
            BigDecimal incomeInvestment, incomeEducation, incomeCharity;
            List<BigDecimal> incomeFromParentJar = (List<BigDecimal>) args[0];
            List<BigDecimal> expensesAndBalance = new ArrayList<BigDecimal>();

            incomeTotal = incomeFromParentJar.get(0);
            incomeNecessities = incomeFromParentJar.get(1);
            incomeSavings = incomeFromParentJar.get(2);
            incomeEntertainment = incomeFromParentJar.get(3);
            incomeInvestment = incomeFromParentJar.get(4);
            incomeEducation = incomeFromParentJar.get(5);
            incomeCharity = incomeFromParentJar.get(6);

            incomeNecessities = incomeNecessities.add((BigDecimal) args[1]);
            .....
            .....
            .....
        }
    }
).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread());
s = imin.subscribe(new Action1<List<BigDecimal>>() {
@Override
public void call(List<BigDecimal> expensesAndBalance) {
    //do plenty of view.settext here
}});
}

And here's how the DbHelper class looks like. Take note that I only display the code for one of the called function.. the other function is pretty much the same (except for the query of course)..

Can anyone pinpoint where did I went wrong?

   public class DbHelper {

        private MySQLiteHelper mySQLiteHelper;
        SqlBrite sqlBrite = new SqlBrite.Builder().build();
        BriteDatabase briteDb;
        Subscription subscription;

        private static DbHelper instance;
        public DbHelper(Context context) {
            mySQLiteHelper = new MySQLiteHelper(context);
            sqlBrite = new SqlBrite.Builder().build();
        }

        public Observable<BigDecimal> getIndividualJarIncomeUpTo(final int endYear, final int endMonth, final int moneyJar){
            briteDb = sqlBrite.wrapDatabaseHelper(mySQLiteHelper,Schedulers.io());
        final String[] args = new String[]{moneyJar + "", endYear + "", endMonth + "", endYear + "", };
        Observable<BigDecimal> myObservable;
        myObservable = briteDb.createQuery(MySQLiteHelper.TABLE_INCOME, "SELECT total FROM " + MySQLiteHelper.TABLE_INCOME +
                " WHERE moneyJar = ? AND ((year = ? AND month <= ?) OR (year < ?)) and isDeleted = 0", args)
                .map(new Func1<SqlBrite.Query, BigDecimal>() {
                    @Override
                    public BigDecimal call(SqlBrite.Query query) {
                        Cursor cursor = query.run();
                        BigDecimal income, incomeTotal = new BigDecimal(0);
                        if (cursor != null) {
                            try {
                                if (cursor.getCount() > 0 && cursor.moveToFirst()) {
                                    do {
                                        income = new BigDecimal(cursor.getString(cursor.getColumnIndex("total")));
                                        incomeTotal = incomeTotal.add(income);
                                    } while (cursor.moveToNext());
                                }
                            } catch (Exception e) {
                                e.printStackTrace();
                            } finally {
                                cursor.close();
                            }
                            if (moneyJar == 1) {
                                Log.v(FILE_NAME, "imini " + endYear + " " + endMonth + " incomeTotal: " + incomeTotal);
                            }
                        }
                        return incomeTotal;
                    }
                });
        return myObservable;
    }

    public void close(){
        if (briteDb != null) {
            briteDb.close();
        }
    }
}

回答1:

I restructured my codes and sql query and lessen the number of observables to only 12 instead of the original 60, and the problem is gone. So basically this issue was caused by bad design on my part.