I am trying to send multiple Json string[each 1 MB] at a time to PHP Server. When i tried to send 10 records its working fine. But if it exceeds 20 records it says OutOfMemoryException
. I seen that android memory size limit t0 15MB - 16MB. But haven't got any clue how to resolve this,
I am using the below code to send multiple records at a time.
/** Upload Data*/
private void submitUploadData(String url, Map<String, String> param)
throws IOException {
URL siteUrl;
try {
siteUrl = new URL(url);
HttpURLConnection conn = (HttpURLConnection) siteUrl
.openConnection();
conn.setRequestMethod("POST");
conn.setDoOutput(true);
conn.setDoInput(true);
DataOutputStream out = new DataOutputStream(conn.getOutputStream());
String content1 = "";
Set getkey = param.keySet();
Iterator keyIter = getkey.iterator();
String content = "";
for (int i = 0; keyIter.hasNext(); i++) {
Object key = keyIter.next();
if (i != 0) {
content += "&"; //Crashing here
}
content += key + "=" + param.get(key); //Crashing here
System.out.println("Content" + content);
}
System.out.println(content);
out.writeBytes(content.trim());
out.flush();
out.close();
BufferedReader in = new BufferedReader(new InputStreamReader(
conn.getInputStream()));
String jsonresponse = "";
while ((jsonresponse = in.readLine()) != null) {
System.out.println(jsonresponse);
if(!jsonresponse.equals("Authorisation Successful")){
updateUploadRecords(jsonresponse);}
}
in.close();
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
Through personal experience I've found that beyond a certain size (which is dependent on the device), it is not feasible to use String concatenation to form / download entities.
In your case using a JsonWriter will help. It writes json tokens to a stream and will not occupy additional memory. When you download bulky json documents use a JsonReader.
I've used both these classes with success.
Maybe it is limited by the memory size of your virtual device!?
Have you tried it by giving it a bigger memory!?
at first glance there's nothing wrong with your code but you're using every possible type of method that is known for being a memory waster and now that you're trying large operations you running out of memory, that was guaranteed to happen.
tips:
str1 += str2 + "other val"
you just created 3 new strings in memory. Use a StringBuilder instead.Instead you should (on the method that is creating that map) to use some type of
OutputStream
to write all that data, already formatted in a temporary file. Then, to upload you'll use some type ofInputStream
to read from this file and write to yourDataOutputStream
Alternative to the Streams is to use some other classes that bases on the same methodology as streams, they are: JsonWriter/JsonReader, but then you also have FileWriter/FileReader if it's not specific Json what you're passing, and don't forget to always wrap those with BufferedReader and BufferedWriter.
You are iterating through it with object. You have the risk that they keep copies etc... Go back to basics and try to use the function
String.split('');
and then iterating through it with a normal loop. Then you know which objects are in memory. When doing the split you get two memory hogging objects, the original string and the array resulting from the split.At the moment you have split the original string you can set the original string to
null
to free up the memory for the garbage collector(maybe even callSystem.gc()
)Then just simply loop through the string doing manipulation by manipulation, keeping the footprint as small as possible.