I've an Android application that posting JSONObject
as a entity by using ByteArrayEntity
object. Here how it looks like:
post.setEntity(new ByteArrayEntity(entity.getBytes("UTF-8")));
result = client.execute(post, handler);
Entity is a String
. Handler is ResponseHandler<String>
and client is a HttpClient
. That's working well on emulator and on some devices. But, sometimes I'm getting OutOfMemoryError while executing on x10i
(also known as XPERIA).
Here is stack:
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)
As I said, I'm just posting a JSONObject as a String. It may be 200 character at most. What's wrong?
Android devices have a per-process memory limit. The default default is 24MB, but some devices have a lower value, eg 16MB or perhaps lower. The X10i appears to have 384MB RAM, which is low for a modern Android device (1GB is now standard), and this may place additional constraints.
I would suggest:
You may find that, just before you are making this call, you are already at the upper limit of memory; the initialisation of the HTTPClient and the call might take you just over the limit. This will be more likely if the OOM occurs on the first call.
If this happens only sporadically, or after a number of calls, you might have a memory leak. DDMS will help you track that down using the get allocations feature.
In case of java.lang.OutOfMemoryError
it's likely that your application keeps references to objects which should be freed. Try to debug this application on this phone, not in emulator.
On the surface, only 200 bytes which are allocated not very often will not run the process out of memory even on Android. Therefore one of these assumptions is wrong. Most likely one of the following is true:
1) More than 200 bytes is being allocated in the failure case (for example, is a new HttpClient being allocated for every call).
2) This code is getting called very often
3) There is already a memory problem (like with images) and this was just the last allocation that took the app past its limits.
How many times has this line of code been the culprit of this problem? If the answer is many then 1) or 2) look likely. Since we do not have all the apps code it is hard to diagnose, but look to the event/circumstance that triggers this code -- is it getting called from a touch or move -- and if so is this happening every millisecond as the user drags their finger across the screen because there is no sleep in the onTouch loop? This is the kind of thing that could vary from platform to platform.
If this line of code has only caused the problem once or twice it may be time to look for a general memory usage problem. Try to determine how close to the memory limit the application is. The allowance varies with Android version, so this may be another reason why you don't see it in the emulator. Try to test with the same Android version that is experiencing the problem.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With