나는 부채 상환 계산기에 대해 수십 번 루프를 반복 할 수 있습니다. 이 루프가하는 여러 가지의메모리 부족 오류 문자열에 실패
하나는 내가 문자열 (쿼리) check_for_special
를 구축 행에서이 OutOfMemory
스택 트레이스를 얻고있다 getSpecialPayment
private double getSpecialPayment(long debt_id, int month) {
int thisMonth = Calendar.getInstance().get(Calendar.MONTH) + 1;
Calendar cal = Calendar.getInstance();
cal.set(Calendar.MONTH, month + thisMonth);
SimpleDateFormat df = new SimpleDateFormat("MMM yyyy", Locale.ENGLISH);
String sMonth = df.format(cal.getTime());
// Line 884 that fails below
String check_for_special = "SELECT payment FROM special_payments WHERE id = " + debt_id + " and month = '" + sMonth + "' LIMIT 1;";
if (!database.isOpen()) {
open();
}
Cursor c = database.rawQuery(check_for_special, null);
if (c.getCount() == 0) {
c.close();
return 0;
} else {
c.moveToFirst();
double amount = c.getDouble(c.getColumnIndex("payment"));
c.close();
return amount;
}
}
라는 메소드를 호출합니다.
java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:300)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:841)
Caused by: java.lang.OutOfMemoryError
at java.lang.AbstractStringBuilder.enlargeBuffer(AbstractStringBuilder.java:94)
at java.lang.AbstractStringBuilder.append0(AbstractStringBuilder.java:145)
at java.lang.StringBuilder.append(StringBuilder.java:216)
at com.---.---.DebtDataSource.getSpecialPayment(DebtDataSource.java:884)
at com.---.---.DebtDataSource.payoffDebt(DebtDataSource.java:469)
at com.---.---.PlannerFragment$PlannerTask.doInBackground(PlannerFragment.java:156)
at com.---.---.PlannerFragment$PlannerTask.doInBackground(PlannerFragment.java:122)
at android.os.AsyncTask$2.call(AsyncTask.java:288)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
... 4 more
이유는 무엇입니까? String
초기화로 인해 오류가 발생할 수 있습니다. 아니면이 시점에서 더 큰 문제가 단순히 실패한 것은 우연의 일치입니까?
편집 :
이 그림은 내 힙 덤프입니다 : 당신은 여기에 당신의 손에 더 큰 문제가
동의 함,이 함수 내에서 생성 된 모든 객체 (눈을 가리고 "수십 번"이라고 함)를 자세히 살펴 봅니다. 예를 들어 CalendarInstance 및 SimpleDateFormat은 한 번 생성되어 다시 사용될 수 있습니다. 또한 문자열 (예 : http://stackoverflow.com/questions/9857073/queries-with-prepared-statements-in-android)에서 rawQuery 대신 매개 변수화 된 쿼리를 고려해보십시오. 단일 쿼리 문자열 인 – CSmith
알았어 고마워. 이걸 사냥해서 메모리 모니터 도구를 사용하는 법을 배워야 할 것 같네요. – KickingLettuce
@KickingLettuce Eclipse MAT를 사용하는 것이 좋습니다. 정말 사용하기 쉽습니다. jmap은 내가 힙 덤프에 사용하는 것이다. –