sqlite - Android huge JSONObject toString goes OutOfMemoryError -
i need read lot of data sqlite database , create formatted json.
i'm achieving having object called requestpayload
which contains arraylist
s in put data read sqlite.
the requestpayload
class has parsejson()
method returns jsonobject
on call tostring()
method obtain json string got written on file.
now, when i've got "small" quantities of data in sqlite goes fine. when i've got lot of data happens:
06-28 09:55:34.121 10857-6799/it.example.sampler e/androidruntime: fatal exception: thread-195240 process: it.example.sampler, pid: 10857 theme: themes:{com.cyanogenmod.trebuchet=overlay:system, com.android.settings=overlay:system, default=overlay:system, iconpack:system, fontpkg:system, com.android.systemui=overlay:system, com.android.systemui.navbar=overlay:system} java.lang.outofmemoryerror: failed allocate 52962812 byte allocation 16764752 free bytes , 41mb until oom @ java.lang.stringfactory.newstringfromchars(native method) @ java.lang.abstractstringbuilder.tostring(abstractstringbuilder.java:629) @ java.lang.stringbuilder.tostring(stringbuilder.java:663) @ org.json.jsonstringer.tostring(jsonstringer.java:430) @ org.json.jsonobject.tostring(jsonobject.java:690) @ it.example.sampler.controllers.network.requestbodyencoder.serialise(requestbodyencoder.java:69) @ it.example.sampler.controllers.network.requestbodyencoder.createpacket(requestbodyencoder.java:50) @ it.example.sampler.services.filestorerunnable.run(filestorerunnable.java:57) @ java.lang.thread.run(thread.java:818) 06-28 09:55:34.509 10857-10857/it.example.sampler e/windowmanager: android.view.windowleaked: activity it.example.sampler.ui.startsamplingactivity has leaked window com.android.internal.policy.phonewindow$decorview{74710d v.e...... r......d 0,0-1026,494} added here @ android.view.viewrootimpl.<init>(viewrootimpl.java:372) @ android.view.windowmanagerglobal.addview(windowmanagerglobal.java:299) @ android.view.windowmanagerimpl.addview(windowmanagerimpl.java:86) @ android.app.dialog.show(dialog.java:319) @ it.example.sampler.ui.startsamplingactivity.executestop(startsamplingactivity.java:305) @ it.example.sampler.ui.startsamplingactivity.onclickedbutton(startsamplingactivity.java:256) @ it.example.sampler.ui.startsamplingactivity$3.onclick(startsamplingactivity.java:190) @ android.view.view.performclick(view.java:5204) @ android.view.view$performclick.run(view.java:21158) @ android.os.handler.handlecallback(handler.java:739) @ android.os.handler.dispatchmessage(handler.java:95) @ android.os.looper.loop(looper.java:148) @ android.app.activitythread.main(activitythread.java:5461) @ java.lang.reflect.method.invoke(native method) @ com.android.internal.os.zygoteinit$methodandargscaller.run(zygoteinit.java:726) @ com.android.internal.os.zygoteinit.main(zygoteinit.java:616)
now code:
the error line method:
private string serialise() throws jsonexception { // serialise string samplestring = mpayload.parsejson().tostring(); // line logger.get().d(log_tag, "serialised payload: -> " + samplestring); return samplestring; }
and if got logcat correctly error during execution of tostring()
method , appears json object big.
how can handle situation?
update: answer @yashjain comment asking size of jsonobject.
after sampling sampling lasted 2 hours had json containing:
- 12 jsonarray containing 155.432
float
s - 2 jsonarray containing 8.393
float
s - 1 jsonarray containing 8.393 custom object containing 5
float
s each (and string) - 1 2d array containing 155.432
int
s
in terms of bytes since float made 4 bytes (i hope i've done calculus correctly) i've got circa:
(12 * 155432 * 4) + (2 * 8393 * 4) + (1 * 8393 * 5) + (1 * 155432 * 4) ~= 8.191.573 bytes
update: i've been asked used compression algorithm. use zlib
via deflater
, deflateroutputstream
java classes.
thus flow is:
- sample data -> store them in
sqlite
- read
sqlite
-> buildrequestpayload
object in memory - convert
requestpayload
objectjsonobject
(with custom custom parser). - convert
jsonobject
string (usingjsonobject
tostring()
method) - compress string bytes (using
getbytes()
) -> encode in base64 - send final base64 string server
edit: respond "possibile duplicate flag" haven't seen question during researches way didn't me since makes use of largeheap
directive (which don't use). there's no accepted answer , answer doesn't provide practical solution.
sorry not giving more feedbacks i've been busy other works , got last in priority queue.
anyhow worked me using google gson
library.
my serialisation method has become simply:
private string serialise() { // serialise return mpayload.tostringfromgson(); }
and method tostringfromgson()
in class payload
is:
public string tostringfromgson() { gsonbuilder gsonbuilder = new gsonbuilder(); gson gson = gsonbuilder.create(); return gson.tojson(this); }
anyhow think can considered temporary patch. in fact noticed memory used application increases dramatically during phase hence think problem postponed , occur heavier loads..
Comments
Post a Comment