Hi fadden,
thanks for your answer and for looking things up in the dalvik source.
Sounds very much like you are right.
I didn't know of dalvik.system.VMRuntime.setMinimumHeapSize() but now
tried it. Invoking that with 4 MB or 5MB has no visible effect. But
invoking it with 8MB solves my problem.
So while my needs are fullfilled now, at least until Android 1.6 or
2.0 comes out and dropps support for setMinimumHeapSize, I had some
insights I want to share:
Interestingly, while doing some benchmarking it turned out that the
real heap size and heap usage is not increased by this. I called
setMinimumHeapSize jsut before the caching/prebuffering starts. I've
compiled my app with different values and used the eclipse DDMS view
to query the heap usage at three important times in my application
life cycle:
Step 1: Start the application and wait for the caching to be done,
then GC
Step 2: Open up another activity that displays a visual list, showing
the first 9 objects, then GC
Step 3: Scroll several times up and down through the list, until
scrolling is smooth, then GC
Without using setMinimumHeapSize:
Step 1: 3,258 used: 2,473
Step 2: 3,445 used: 2,571
Step 3: 3,508 used: 2,639
runtime.setMinimumHeapSize(400);
runtime.setTargetHeapUtilization(0.9f);
Step 1: 3,195 used: 2,485
Step 2: 3,508 used: 2,580
Step 3: 3,508 used: 2,583
runtime.setMinimumHeapSize(500);
Step 1: 3,250 used: 2,386
Step 2: 3,258 used: 2,517
Step 3: 3,383 used: 2,595
runtime.setMinimumHeapSize(800);
Step 1: 3,320 used: 2,480
Step 2: 3,320 used: 2,519
Step 3: 3,320 used: 2,531
As you can see, there is now big difference in those values. Anyway,
only when setting the heap to 8MB, none of my weakly referenced
objects where thrown away, and in Step 3 I instantly get a smooth
scrolling list.
The usage is always around 76%. I noticed there is a method
setTargetHeapUtilization and tried it once, supplying 0.9f as
parameter. As you can see in the above numbers, doing it results in
the same actual usage around 76%.
with best regards,
Brian schimmel
On 23 Jul., 22:16, fadden fad...@android.com wrote:
On Jul 23, 5:50 am, brian.schim...@googlemail.com
brian.schim...@googlemail.com wrote:
Actually, something like that happens:
Object 1 is cached
Object 2 is cached
Object 3 is cached
Object 4 is cached
Object 5 is cached
Objects 1 to 4 are cleared by the GC
Object 6 is cached
Object 7 is cached
Object 8 is cached
Object 9 is cached
Objects 5 to 8 are cleared by the GC
and so on.
I don't believe this is the desired behavior. Looking at tryMalloc()
in dalvik/vm/alloc/Heap.c, it initially calls gcForMalloc(false),
which should not be attempting to collect soft references. Only
later, when confronted with the possibility of throwing OOM, does it
call gcForMalloc(true).
Hmm. In dvmHeapSizeChanged() there's a SOFT_REFERENCE_GROWTH_SLACK
value that appears to be trying to strike a balance between expanding
without limit and collecting objects. If there's no cap we might fill
16MB with softly-reachable objects before we discard any of them,
which isn't desirable on a device that has multiple applications
resident in memory. It appears the function wants the GC to collect
some of the soft references, which sounds good, but it looks like
SR_COLLECT_SOME doesn't receive special treatment during the mark
sweep. In the current implementation, it's all or nothing.
So my guess is you've got more than 128KB of softly-reachable objects
(i.e. the things that are softly referenced, and the things that are
only reachable through them). When the GC has to choose between
expanding the current heap size and chucking the soft references, it's
choosing to discard some, which in the current implementation means
all.
The observed behavior changes after you have a bunch of other stuff
allocated, because the soft limit is higher, and the GC doesn't have
to choose between expanding the heap and collecting the soft
references.
You might be able to work around this behavior by calling
dalvik.system.VMRuntime.setMinimumHeapSize() (which really shouldn't
be exposed in the API, but there it is). If you start it out at 4MB
that might prevent you from thrashing like this right after the app
starts up. I think the issue will come back if you manage to get
close to the soft limit again, but I don't think that's avoidable
without a change to the GC behavior. (There are some kluges you could
employ to suppress the behavior, like periodically grabbing hard
references to all cached items, allocating something large, discarding
it, and un-refing the cache entries, but that's ugly and might not
work anyway.)
I'll file a bug against the GC.
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google
Groups Android Developers group.
To post to this group, send email to android-developers@googlegroups.com
To unsubscribe from this group,