11-06 14:52:51.011: D/dalvikvm(1992): GC_FOR_MALLOC freed 6 objects / 448 bytes in 61ms
11-06 14:52:51.431: E/dalvikvm-heap(1992): Out of memory on a 9634-byte allocation.
11-06 14:52:51.431: I/dalvikvm(1992): "Thread-10" prio=5 tid=9 RUNNABLE
11-06 14:52:51.431: I/dalvikvm(1992): | group="main" sCount=0 dsCount=0 s=N obj=0x442d3df0 self=0x282de8
11-06 14:52:51.431: I/dalvikvm(1992): | sysTid=2012 nice=0 sched=0/0 cgrp=unknown handle=2631808
11-06 14:52:51.431: I/dalvikvm(1992): | schedstat=( 414545903000 97070402000 6375089 )
11-06 14:52:51.431: I/dalvikvm(1992): at java.lang.String.<init>(String.java:~468)
11-06 14:52:51.431: I/dalvikvm(1992): at java.lang.AbstractStringBuilder.toString(AbstractStringBuilder.java:659)
11-06 14:52:51.431: I/dalvikvm(1992): at java.lang.StringBuilder.toString(StringBuilder.java:664)
11-06 14:52:51.431: I/dalvikvm(1992): at org.json.JSONStringer.toString(JSONStringer.java:430)
11-06 14:52:51.431: I/dalvikvm(1992): at org.json.JSONArray.toString(JSONArray.java:545)
11-06 14:52:51.431: I/dalvikvm(1992): at java.lang.String.valueOf(String.java:1904)
11-06 14:52:51.431: I/dalvikvm(1992): at org.json.JSON.toString(JSON.java:86)
11-06 14:52:51.431: I/dalvikvm(1992): at org.json.JSONObject.getString(JSONObject.java:511)
11-06 14:52:51.431: I/dalvikvm(1992): at com.unitas.common.ParsingJson.parsingRecOrd(ParsingJson.java:141)
11-06 14:52:51.431: I/dalvikvm(1992): at com.unitas.kitchen.ActivityKitchenClientD.run(ActivityKitchenClientD.java:418)
11-06 14:52:51.431: I/dalvikvm(1992): at java.lang.Thread.run(Thread.java:1096)
11-06 14:52:51.621: I/dalvikvm-heap(1992): Clamp target GC heap from 17.429MB to 16.000MB
11-06 14:52:51.621: D/dalvikvm(1992): GC_EXPLICIT freed 1871 objects / 88576 bytes in 58ms
11-06 14:52:54.271: I/dalvikvm-heap(1992): Clamp target GC heap from 17.478MB to 16.000MB
11-06 14:52:54.271: D/dalvikvm(1992): threadid=9: still suspended after undo (sc=1 dc=1 s=Y)
11-06 14:52:54.281: D/dalvikvm(1992): GC_FOR_MALLOC freed 5729 objects / 388776 bytes in 56ms
11-06 14:55:46.291: D/dalvikvm(1992): Debugger has detached; object registry had 247 entries
11-06 14:55:46.291: W/dalvikvm(1992): threadid=9: thread exiting with uncaught exception (group=0x4001d868)
11-06 14:55:46.401: I/dalvikvm-heap(1992): Clamp target GC heap from 17.526MB to 16.000MB
11-06 14:55:46.401: D/dalvikvm(1992): GC_FOR_MALLOC freed 2860 objects / 171480 bytes in 94ms
11-06 14:55:46.431: E/AndroidRuntime(1992): FATAL EXCEPTION: Thread-10
11-06 14:55:46.431: E/AndroidRuntime(1992): java.lang.OutOfMemoryError
11-06 14:55:46.431: E/AndroidRuntime(1992): at java.lang.String.<init>(String.java:468)
11-06 14:55:46.431: E/AndroidRuntime(1992): at java.lang.AbstractStringBuilder.toString(AbstractStringBuilder.java:659)
11-06 14:55:46.431: E/AndroidRuntime(1992): at java.lang.StringBuilder.toString(StringBuilder.java:664)
11-06 14:55:46.431: E/AndroidRuntime(1992): at org.json.JSONStringer.toString(JSONStringer.java:430)
11-06 14:55:46.431: E/AndroidRuntime(1992): at org.json.JSONArray.toString(JSONArray.java:545)
11-06 14:55:46.431: E/AndroidRuntime(1992): at java.lang.String.valueOf(String.java:1904)
11-06 14:55:46.431: E/AndroidRuntime(1992): at org.json.JSON.toString(JSON.java:86)
11-06 14:55:46.431: E/AndroidRuntime(1992): at org.json.JSONObject.getString(JSONObject.java:511)
11-06 14:55:46.431: E/AndroidRuntime(1992): at com.unitas.common.ParsingJson.parsingRecOrd(ParsingJson.java:141)
11-06 14:55:46.431: E/AndroidRuntime(1992): at com.unitas.kitchen.ActivityKitchenClientD.run(ActivityKitchenClientD.java:418)
11-06 14:55:46.431: E/AndroidRuntime(1992): at java.lang.Thread.run(Thread.java:1096)
위는 에러 코드이구요. 보시는 것과 같이 out of memory error가 납니다.
아래는 문제의 함수 부분입니다...
public JsonHeaderInfo parsingRecOrd(String jString) {
jsonHeader = new JsonHeaderInfo();
try {
jsonObject = new JSONObject(jString);
jsonHeader.setJob_dt(jsonObject.getString("JOB_DT").toString());
jsonHeader.setJob_type(jsonObject.getString("JOB_TYPE").toString());
jsonHeader.setClient(jsonObject.getString("CLIENT").toString());
jsonHeader.setWcc(jsonObject.getString("WCC").toString());
jsonHeader.setRec_cnt(jsonObject.getString("REC_CNT").toString());
jsonHeader.setStatus(jsonObject.getString("STATUS").toString());
jsonHeader.setMessage(jsonObject.getString("MESSAGE").toString());
if(!jsonObject.has("DETAIL")) {
Log.d("json", "ReceiveOrderInfo_DETAIL이 존재 하지 않습니다.");
jsonHeader.setExceptionJson(CommonValue.JSON_EXCEPTION_DETAIL);
return jsonHeader;
}
jArr = new JSONArray(jsonObject.getString("DETAIL"));
int length = jArr.length();
for (int i = 0; i < length; i++) {
if(!jArr.getJSONObject(i).has("ROWS")) {
Log.d("json", "ReceiveOrderInfo Rows가 존재 하지 않습니다.");
jsonHeader.setExceptionJson(CommonValue.JSON_EXCEPTION_ROWS);
return jsonHeader;
}
jArr2 = new JSONArray(jArr.getJSONObject(i).getString("ROWS"));
int length21 = jArr2.length();
for(int j = 0; j < length21; j++) {
if(!jArr2.getJSONObject(j).getString("KITCHEN_DV").equals("1"))
continue;
TempsOrderInfo temp = new TempsOrderInfo(
jArr2.getJSONObject(j).getLong("ID")
,jArr2.getJSONObject(j).getString("KITCHEN_DV")
,jArr2.getJSONObject(j).getString("ORDER_NO")
,jArr2.getJSONObject(j).getString("INPUT_DT")
,jArr2.getJSONObject(j).getString("MENU_DV")
,jArr2.getJSONObject(j).getString("FOOD_NO")
,jArr2.getJSONObject(j).getString("FOOD_NM")
,jArr2.getJSONObject(j).getString("FOOD_QTY")
,jArr2.getJSONObject(j).getString("CANCEL_YN")
,jArr2.getJSONObject(j).getString("CANCEL_DT")
,jArr2.getJSONObject(j).getString("COMPLETE_YN")
,jArr2.getJSONObject(j).getString("COMPLETE_DT")
,jArr2.getJSONObject(j).getString("ETC_1")
,jArr2.getJSONObject(j).getString("ETC_2")
,jArr2.getJSONObject(j).getString("DONE_YN")
,jArr2.getJSONObject(j).getString("DONE_DT") );
CommonValue.tempArrayList.add(temp);
}
}
return jsonHeader;
} catch (JSONException je) {
Log.d("json", "json에러", je);
jsonHeader.setExceptionJson(CommonValue.JSON_HEADER_EXCEPTION);
return jsonHeader;
} catch (Exception e) {
Log.d("json", "Exception", e);
jsonHeader.setExceptionJson(CommonValue.JSON_HEADER_EXCEPTION);
return jsonHeader;
} finally {
jsonObject = null;
jArr = null;
jArr2 = null;
System.gc();
}
}
클라이언트(안드로이드 디바이스) 에서 매분마다 새로고침을 요청하면
서버에서 디비의 내용을 Select 하여 TCP/IP 소켓으로 클라이언트에게 JSON포맷으로 5KB 가량되는 문자열을 던져줍니다.
그걸 위 함수를 통해 파싱하여 어레이 리스트에 담아주게 되는 형식인데요...
오랜시간이 지나보니 메모리 문제로 뻑~ 나더라구요....
이것저것 알아보니 heap memory 오버플로우 나는 것 같아요. 현재 테스트 디바이스는 힙용량이 16MB입니다.
공개배포용이 아니고, 디바이스가 하나뿐이라, 프로요2.2 버전에서만 사용해야하는 상황이구요.
지금은 JSON심플 라이브러리를 사용하고 있습니다.
함수중 빨간 부분에서 대부분 멈추게 됩니다.
힙메모리를 강제로 해제한다는 System.gc();를 군데군데 넣어 써봐도 똑같고..
객체마다 null로 초기화하여 가비지 컬렉션에 걸리게 해보려했지만 똑같네요..
블로그에서 매니페스트에 LargeHeap 설정하는 방법을 본 것같지만, 메모리 해제가 전혀 되지 않아
해결점이 되지 않습니다...
보통 안드로이드에서 아웃 오브 메모리 에러가 비트맵으로 인해 발생되기 쉽다는 것을 인지하고는 있었으나,
이런 경우에 메모리 문제가 발생한게 처음이라.. 무척 고민입니다..
작은 답변이라도 좋으니 도움을 요청합니다!
랍스타님 사랑하고 고맙고 감사합니다!
혹시나 하여 static으로 다른 클래스에서 선언한 ArrayList<>때문에 뭔가 삐긋했나 싶어,
글의 함수 부분에 ArrayList<> 부분을 매개변수, 그리고 리턴으로 넘기고,
소스도 랍스타님이 예를 드신것처럼 정리를 해봤습니다.
두번을 놀려 노가다 테스트를 해보니, 빨간글씨부분의 메모리 누수관련 에러가 보이지 않네요..
허나 Heap 정보를 보니 메모리가 해제 되지 않고 증가하는 부분은 고쳐지지 않아 아쉽네요 ㅠㅠ
이젠.. 다른 부분에서 에러가 뜨네요;;;
public void run() {
isStop = false;
try {
oos = new ObjectOutputStream(socket.getOutputStream());
ois = new ObjectInputStream(socket.getInputStream());
oos.writeObject(CommonValue.CONNECT_OK);
} catch (Exception ee) {
ee.printStackTrace();
}
while (!isStop) {
try {
message = (String) ois.readObject();
} catch (Exception e) {
e.printStackTrace();
}
if (message == null) {
} else {
ParsingJson pj = new ParsingJson();
temp = pj.parsingRecOrd(message);
if( temp != null) {
handler.post(new Runnable() {
public void run() {
displayGridItem();
}
});
}
message = null;
}
}
}
(소스가 이리저리 지저분한건;; 에러때문에 계속 테스트 해본다고.. 보기 힘드시죠.. )
아이고.. 왜 이번엔 ObjectInputStream 에서 비스무리한 에러가 뜨는 걸까요...
11-06 17:31:46.221: E/dalvikvm-heap(11887): Out of memory on a 39884-byte allocation.
11-06 17:31:46.221: I/dalvikvm(11887): "Thread-10" prio=5 tid=9 RUNNABLE JIT
11-06 17:31:46.221: I/dalvikvm(11887): | group="main" sCount=0 dsCount=0 s=N obj=0x442d42e8 self=0x282cb8
11-06 17:31:46.221: I/dalvikvm(11887): | sysTid=11910 nice=0 sched=0/0 cgrp=unknown handle=2114624
11-06 17:31:46.221: I/dalvikvm(11887): | schedstat=( 14162934000 2880014000 22502 )
11-06 17:31:46.221: I/dalvikvm(11887): at java.lang.String.<init>(String.java:~468)
11-06 17:31:46.221: I/dalvikvm(11887): at org.apache.harmony.luni.util.Util.convertUTF8WithBuf(Util.java:265)
11-06 17:31:46.221: I/dalvikvm(11887): at java.io.DataInputStream.decodeUTF(DataInputStream.java:445)
11-06 17:31:46.221: I/dalvikvm(11887): at java.io.DataInputStream.decodeUTF(DataInputStream.java:437)
11-06 17:31:46.221: I/dalvikvm(11887): at java.io.DataInputStream.readUTF(DataInputStream.java:432)
11-06 17:31:46.221: I/dalvikvm(11887): at java.io.ObjectInputStream.readNewString(ObjectInputStream.java:2194)
11-06 17:31:46.221: I/dalvikvm(11887): at java.io.ObjectInputStream.readNonPrimitiveContent(ObjectInputStream.java:931)
11-06 17:31:46.221: I/dalvikvm(11887): at java.io.ObjectInputStream.readObject(ObjectInputStream.java:2285)
11-06 17:31:46.221: I/dalvikvm(11887): at java.io.ObjectInputStream.readObject(ObjectInputStream.java:2240)
11-06 17:31:46.221: I/dalvikvm(11887): at com.unitas.kitchen.ActivityKitchenClientD.run(ActivityKitchenClientD.java:400)
11-06 17:31:46.221: I/dalvikvm(11887): at java.lang.Thread.run(Thread.java:1096)
11-06 17:31:46.241: W/dalvikvm(11887): threadid=9: thread exiting with uncaught exception (group=0x4001d868)
11-06 17:31:46.241: E/AndroidRuntime(11887): FATAL EXCEPTION: Thread-10
11-06 17:31:46.241: E/AndroidRuntime(11887): java.lang.OutOfMemoryError
11-06 17:31:46.241: E/AndroidRuntime(11887): at java.lang.String.<init>(String.java:468)
11-06 17:31:46.241: E/AndroidRuntime(11887): at org.apache.harmony.luni.util.Util.convertUTF8WithBuf(Util.java:265)
11-06 17:31:46.241: E/AndroidRuntime(11887): at java.io.DataInputStream.decodeUTF(DataInputStream.java:445)
11-06 17:31:46.241: E/AndroidRuntime(11887): at java.io.DataInputStream.decodeUTF(DataInputStream.java:437)
11-06 17:31:46.241: E/AndroidRuntime(11887): at java.io.DataInputStream.readUTF(DataInputStream.java:432)
11-06 17:31:46.241: E/AndroidRuntime(11887): at java.io.ObjectInputStream.readNewString(ObjectInputStream.java:2194)
11-06 17:31:46.241: E/AndroidRuntime(11887): at java.io.ObjectInputStream.readNonPrimitiveContent(ObjectInputStream.java:931)
11-06 17:31:46.241: E/AndroidRuntime(11887): at java.io.ObjectInputStream.readObject(ObjectInputStream.java:2285)
11-06 17:31:46.241: E/AndroidRuntime(11887): at java.io.ObjectInputStream.readObject(ObjectInputStream.java:2240)
11-06 17:31:46.241: E/AndroidRuntime(11887): at com.unitas.kitchen.ActivityKitchenClientD.run(ActivityKitchenClientD.java:400)
11-06 17:31:46.241: E/AndroidRuntime(11887): at java.lang.Thread.run(Thread.java:1096)
혹시 이부분도 뭔가 빠졌다던가 이상한 부분이 안보이시는지........
보이신다면.. 한수 가르쳐주길 부탁드려요...
그래도 뭔가 하나씩 해결되는 느낌은 오고있어서 힘이 나네요!!감사합니다!
움.. 비슷한 증상에 대한 답변이 있는걸 찾았는데
도움이 되실지 모르겠네요..
http://stackoverflow.com/questions/5842201/out-of-memory-error-when-putting-large-json-inputstream-to-string
스트링에 대한 충분히 큰 싱글 메모리 블럭이 없어서 일정 크기 이상의 스트링에 대한 이슈가 발생하는듯한데
답변에는 JSONReader를 사용하면 된다는데.. 자세한건 직접 해보심이;;
http://developer.android.com/reference/android/util/JsonReader.html <= JSONReader 관련 레퍼런스
정확한 답변 못 드려 죄송해요 ㅠㅠ
확실하진 않구요 제가 자주쓰는 형식과 조금 달라서..
참고가 되실까 하고 글 남깁니다.
jArr2 = new JSONArray(jArr.getJSONObject(i).getString("ROWS"));
JSONObject jo;
JSONArray ja;
try {
jo = new JSONObject(str_json);
ja = jo.getJSONArray("data");
for (int i = 0; i < ja.length(); i++) {
JSONObject order = ja.getJSONObject(i);
arrList.add(order.getString("text"));
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}