2012-12-17 47 views
11

मेरे पास एक एंड्रॉइड एप्लिकेशन है जो को ByteArrayEntity ऑब्जेक्ट का उपयोग करके एक इकाई के रूप में पोस्ट करता है। यह इस प्रकार से लगता है कि:HttpClient.execute फेंक आउट आउटफॉर्मरीर

post.setEntity(new ByteArrayEntity(entity.getBytes("UTF-8"))); 
result = client.execute(post, handler); 

इकाई एक String है। हैंडलर ResponseHandler<String> है और ग्राहक HttpClient है। यह एमुलेटर और कुछ उपकरणों पर अच्छी तरह से काम कर रहा है। लेकिन, कभी-कभी मुझे x10i (जिसे XPERIA भी कहा जाता है) पर निष्पादित करते समय OutOfMemoryError प्राप्त हो रहा है।

यहाँ ढेर है:

java.lang.OutOfMemoryError 
at org.apache.http.impl.io.AbstractSessionInputBuffer.init(AbstractSessionInputBuffer.java:79) 
at org.apache.http.impl.io.SocketInputBuffer.<init>(SocketInputBuffer.java:93) 
at org.apache.http.impl.SocketHttpClientConnection.createSessionInputBuffer(SocketHttpClientConnection.java:83) 
at org.apache.http.impl.conn.DefaultClientConnection.createSessionInputBuffer(DefaultClientConnection.java:170) 
at org.apache.http.impl.SocketHttpClientConnection.bind(SocketHttpClientConnection.java:106) 
at org.apache.http.impl.conn.DefaultClientConnection.openCompleted(DefaultClientConnection.java:129) 
at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:171) 
at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164) 
at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119) 
at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:359) 
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:580) 
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:678) 
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:652) 
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:641) 
at com.test.application.api.Request.post(Request.java:102) 
at com.test.application.api.API.getResult(API.java:123) 
at com.test.application.api.APITask.doInBackground(APITask.java:127) 
at com.test.application.api.APITask.doInBackground(APITask.java:1) 
at android.os.AsyncTask$2.call(AsyncTask.java:185) 
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:306) 
at java.util.concurrent.FutureTask.run(FutureTask.java:138) 
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088) 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581) 
at java.lang.Thread.run(Thread.java:1019) 

जैसा कि मैंने कहा, मैं सिर्फ एक स्ट्रिंग के रूप में एक JSONObject पोस्टिंग कर रहा हूँ। यह सबसे अधिक 200 चरित्र हो सकता है। क्या गलत है?

+0

सर्वर से प्रतिक्रिया का आकार क्या है? –

+0

यह लगभग 5-6 केबी है। –

+2

उदाहरण के लिए इसी तरह की त्रुटियां हैं http://stackoverflow.com/questions/3055614/out-of-memory-error-my-apps-fault, लेकिन ऐसा लगता है कि सामान्य स्मृति उपयोग से संबंधित है, AbstractSessionInputBuffer से अलग नहीं है । –

उत्तर

5

एंड्रॉइड डिवाइसों में प्रति-प्रक्रिया मेमोरी सीमा है। डिफ़ॉल्ट डिफ़ॉल्ट 24 एमबी है, लेकिन कुछ उपकरणों के पास कम मान है, उदाहरण के लिए 16 एमबी या शायद कम। X10i में 384 एमबी रैम है, जो आधुनिक एंड्रॉइड डिवाइस (1 जीबी अब मानक है) के लिए कम है, और इससे अतिरिक्त बाधाएं हो सकती हैं।

मेरा सुझाव है:

  1. सबसे पहले अपने डिवाइस पर प्रति प्रक्रिया सीमा की जाँच करें। जांचने के लिए ActivityManager.getMemoryClass() का उपयोग करें।
  2. DDMS का उपयोग करके अपने वास्तविक मेमोरी उपयोग को देखें।

आप यह पाते हैं कि, आप यह कॉल करने से ठीक पहले, आप पहले से ही स्मृति की ऊपरी सीमा पर हैं; HTTP क्लाइंट और कॉल का प्रारंभिकरण आपको सीमा से अधिक ले सकता है। यदि ओओएम पहले कॉल पर होता है तो यह अधिक संभावना होगी।

यदि यह केवल स्पोरैडिक होता है, या कई कॉल के बाद, आपके पास मेमोरी लीक हो सकती है। डीडीएमएस get allocations सुविधा का उपयोग करके इसे ट्रैक करने में आपकी सहायता करेगा।

+0

सुझावों के लिए धन्यवाद, जैसा कि आपने निर्देश दिया था, मैं फिर से देखूंगा। –

1

java.lang.OutOfMemoryError के मामले में यह संभव है कि आपका एप्लिकेशन उन वस्तुओं के संदर्भ रखता है जिन्हें मुक्त किया जाना चाहिए। इस एप्लिकेशन पर इस एप्लिकेशन को डीबग करने का प्रयास करें, एम्यूलेटर में नहीं।

1

सतह पर, केवल 200 बाइट जिन्हें आवंटित नहीं किया जाता है, वे एंड्रॉइड पर भी स्मृति से बाहर नहीं चलेंगे। इसलिए इन धारणाओं में से एक गलत है। सबसे अधिक संभावना निम्न में से एक है:

1) विफलता मामले में 200 से अधिक बाइट आवंटित किए जा रहे हैं (उदाहरण के लिए, प्रत्येक कॉल के लिए आवंटित एक नया एचटीपी क्लाइंट है)।

2) इस कोड को कहा जाता है हो रही बहुत अक्सर

3) वहां पहले से ही एक स्मृति समस्या (छवियों के साथ की तरह है) और यह सिर्फ पिछले आवंटन कि इसकी सीमाओं अतीत एप्लिकेशन ले लिया था।

कोड की इस पंक्ति को कितनी बार इस समस्या का दोषी पाया गया है? यदि उत्तर कई है तो 1) या 2) संभावना देखें। चूंकि हमारे पास सभी ऐप कोड नहीं हैं, इसका निदान करना मुश्किल है, लेकिन इस कोड को ट्रिगर करने वाले ईवेंट/परिस्थिति को देखें - क्या इसे स्पर्श या स्थान से बुलाया जा रहा है - और यदि ऐसा होता है तो यह प्रत्येक मिलीसेकंड उपयोगकर्ता के रूप में होता है स्क्रीन पर अपनी उंगली खींचती है क्योंकि टच लूप में कोई नींद नहीं है? यह ऐसी चीज है जो मंच से मंच तक भिन्न हो सकती है।

यदि कोड की इस पंक्ति ने केवल एक या दो बार समस्या का कारण बना दिया है तो यह सामान्य स्मृति उपयोग समस्या को देखने का समय हो सकता है। यह निर्धारित करने का प्रयास करें कि एप्लिकेशन की स्मृति सीमा कितनी करीब है। भत्ता एंड्रॉइड संस्करण के साथ भिन्न होता है, इसलिए यह एक और कारण हो सकता है कि आप इसे एमुलेटर में क्यों नहीं देखते हैं। समस्या का सामना कर रहे एक ही एंड्रॉइड संस्करण के साथ परीक्षण करने का प्रयास करें।