pthread_create失败:无法分配1064960字节堆栈:内存不足

时间:2017-03-25 16:59:37

标签: android android-fragments rx-java rx-android sqlbrite

我有两个片段,在这两个片段中,它将执行使用sqlbrite的代码。虽然应用程序在正常使用情况下不会崩溃,但问题是,如果我在短时间内多次来回加载这两个片段,应用程序将因此错误而崩溃。

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"

其中一个片段有大约50个Observable,然后使用Observable.combineLatest进行组合。这是片段的代码片段(另一个片段有类似的代码)。下面基本上是我的代码的简化版本。

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
}});
}

以下是DbHelper类的外观。请注意,我只显示其中一个被调用函数的代码..另一个函数几乎相同(当然除了查询)..

任何人都可以查明我哪里出错了吗?

   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 个答案:

答案 0 :(得分:0)

我重构了我的代码和sql查询,并将可观察数量减少到只有12而不是原来的60,问题就消失了。所以基本上这个问题是由于我的设计不好造成的。