2017-03-25 76 views
0

我有兩個片段,其中包含這兩個片段,它將執行使用sqlbrite的代碼。雖然應用程序在正常使用情況下不會崩潰,但問題是,如果我在短時間內多次來回加載這兩個片段,則該應用程序會因此錯誤而崩潰。pthread_create失敗:無法分配1064960字節的堆棧:內存不足

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.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(); 
     } 
    } 
} 
+0

看起來像一般的android遊標/內存問題,我會建議確保所有遊標都正確關閉,儘管代碼似乎很好(可能取消訂閱不處理遊標關閉權限?),您應該嘗試使用StrictMode跟蹤打開的遊標。除此之外它可能是一個普遍的內存不足問題,請嘗試確定進程大小以查看它是否有關聯。 – yosriz

+0

@yosriz。當我啓用嚴格模式時,當方向更改時,應用程序會崩潰,並顯示一些打開的遊標未關閉的消息。正如你所看到的,我已經在最後添加了cursor.close()。我不知道我知道任何其他方法來關閉遊標。 – imin

+0

爲了確保達到cursor.close(),我在調試中運行應用程序,並在所有cursor.close()中放置制動點,並且達到所有制動點。 – imin

回答

0

我重構了我的代碼和sql查詢,並將可觀察次數減少到僅12而不是原來的60,問題就消失了。所以基本上這個問題是由我的糟糕設計造成的。

相關問題