i'm investigating memory leak in legacy bb7 app, developed os 4.5 devs no longer in company. hole big device degrades time , puts device in sluggish state in few hours of use. gets slower because dreaded black clock appears in screen increasing frequency simple operations. i've confirmed debugger black clock appears when garbage collector fires in, , no other heavy processing taking place during these intervals. apparently these automatic gc operations not aleviate memory shortage.
i've inspected process app memory using blackberry objects view in bb plugin eclipse. i've not seen abnormal number of instances of kind inside process. interestingly, great number of instances of class model appear live in root process ram (pid=0) despite being created app process. , appear leaked due iterations on persistent vector holds them (for example: there 100 instances in persistent store, after few iterations on persistent vector, there 2000 instances in root process ram. 1900 instances clones of ones in persistence). debugger on, can see instances keep piling in ram , not collected brief automatic gc can see in console, removed when manually force gc debugger (which takes considerably longer run).
the main suspect dao class kept in runtimestore singleton instance (must called alternate entry points too). holds reference bigvector saved in persistentstore, , contains instances of model class above mentioned. shortened version:
public class leakydao { private long persistentstoreid; private long runtimestoreid; private persistentobject persistentobject; private bigvector bigvector; private leakydao(long id_p, long id_r) { persistentstoreid = id_p; runtimestoreid = id_r; persistentobject = persistentstore.getpersistentobject(persistentstoreid); object o = persistentobject.getcontents(); if(o instanceof bigvector){ bigvector = (bigvector) o; } else { bigvector = new bigvector(); persistentobject.setcontents(bigvector); } } public static synchronized leakydao getinstance(long idpersist, long idruntime) { runtimestore rs = runtimestore.getruntimestore(); leakydao dao = (leakydao) rs.get(idruntime); if (dao == null) { dao = new leakydao(idpersist, idruntime); try { rs.put(idruntime, dao); } catch (illegalargumentexception e) { //already exists } } return dao; } public synchronized object get(int index) { return objectgroup.expandgroup(bigvector.elementat(index)); } public synchronized void insertat(int index, persistable p) { objectgroup.creategroupignoretoobig(p); if (index >= bigvector.size()) { bigvector.addelement(p); } else { bigvector.insertelementat(p, index); } persistentobject.setcontents(bigvector); persistentobject.commit(); } } is there horribly wrong class i'm overlooking? @ point can't yet confirm these instances cause of problem because app behaves quite diferently when plugged debugger. possible that, due bug in os (or known behaviour) instances being leaked after calling repeatedly get or insertat?
update
problems automatic garbage collection , outofmemoryerrors observed when debugger on. when not in debug mode, automatic gc work expected, think there's problem debugger. i've had few resets when in objects view.
i see every 'get' calls expandgroup, , every insert calls creategroup. don't think these functions make attempt @ being efficient. meaning copy objects each time, if isn't necessary.
is code uses these objects modifying them? or, if there modification, can narrow down, , make cases use 'getmutable' ? if can either of those, you'll able remove 'creategroup' insertat function, , remove 'expandgroup' function, , save on object copies.
Comments
Post a Comment