Hi Enno,
>
> How big is kaffe?
>
> I know, that's a broad question, but I guess this is the right place to ask.
> What I'm thinking is, what would be the minimum hardware requirement for
> running kaffe, in terms of memory? Say, if I'd strip a few parts like the
> awt, rmi, etc.
>
> Would a minimum working set (able to run a console application) run on an
> ARM with 2 or 4 MB? And how complex would an applet have to be until it
> breaks that barrier?
> , ,
I recommend you use the --with-stats option when configuring Kaffe.
This add the "-vmstats" cmd line switch; try "-vmstats all" to get a complete
statistics (see stats.[ch] for how to add your own statistics.)
It produces a lot of output about memory consumption and other stuff.
To test it, I ran Kaffe's appletviewer on a little game applet
http://www.eagle-i.com/JAVA/game1.html (Coal To Diamonds by Eagle Berns) (*)
Here's the cmdline I supplied:
kaffe -ms 600k -as 32k -vmstats all -verbosemem \
kaffe.applet.AppletViewer coal.html
(start with 600k heap space, increment by 32k, show all vmstats
and also show verbose gc statistics at each run)
Here's the output I got after playing the game once and exiting
the appletviewer:
This is the last output from the last gc:
<GC: heap 2048K, total before 1871K, after 1658K (17484/15048 objs)
19.0% free, alloced 479K (#2739), marked 389K, swept 212K (#2436)
17 objs (0K) awaiting finalization>
This means that the total size of the managed heap is 2MB, that
1.871 were allocated when we decided to gc, after the gc, there
were 1658K still alive, which means 19.0% is free.
We had to mark 389K (meaning that ca. 1658-389 about 1.3MB is
data that is fixed and doesn't have to walked), we were able
to free 2436 objects occupying 212KBytes.
-verbosemem also shows how the used memory divvies up between
different allocation types:
Memory statistics:
------------------
j.l.String: Nr 268 Mem 8K other-nowalk: Nr 3 Mem 0K
obj-no-final: Nr 220 Mem 8K prim-arrays: Nr 297 Mem 95K
ref-arrays: Nr 47 Mem 10K j.l.Class: Nr 241 Mem 26K
obj-final: Nr 55 Mem 1K java-bytecode: Nr 1704 Mem 74K
exc-table: Nr 126 Mem 4K jitcode: Nr 637 Mem 241K
static-data: Nr 109 Mem 4K constants: Nr 217 Mem 160K
other-fixed: Nr 6195 Mem 490K dtable: Nr 195 Mem 74K
methods: Nr 211 Mem 186K fields: Nr 141 Mem 24K
utf8consts: Nr 3848 Mem 152K interfaces: Nr 139 Mem 2K
locks: Nr 44 Mem 1K thread-ctxts: Nr 110 Mem 82K
gc-refs: Nr 241 Mem 5K
And this is part of the vmstats produced statistics when closing the app.
Note that between the last gc and this, some objects may have been allocated/
deallocated. [**]
#
#CUMULATIVE COUNTERS
#FACILITY VISITS FINAL MAX AVG PER HIT
#------------------------ ----------- -------------- -------------- -----------
jitmem-codeblock 1550 0 8456 0.00
jitmem-temp 14 70432 70432 5030.86
vmmem-jar files 3181 232122 244306 72.97
vmmem-class entry pool 237 5688 5688 24.00
gcmem-gcable objects 8553 164561 371969 19.24
vmmem-libltdl 98 1424 3360 14.53
gcmem-fixed objects 50628 1572854 1611382 31.07
gcmem-system pages 44 2097152 2097152 47662.55
#
#USER-DEFINED COUNTERS
#<------ BEGIN `class-pool' ------>
#DUMPING CLASSPOOL MEMORY
#MISC MISCFIX JCODE BCODE CLASS
#------ ------- ------- ------- --------------
... list of classes cut ....
489.97 153.66 263.16 71.65 KBytes
#<------ END `class-pool' ------>
Here's an off-the-cuff analysis of what's going on.
A plain i386 kaffe with jit and all options (awt etc.) enabled can run
simple applets in about 2MB. This does not include memory that may be
allocated by your Xlib or libc. Ca. 241 classes are loaded at this point.
Ca. 1.6 MB of the heap is actually alive in this snapshot taken by
-verbosemem after the last gc. Out of these 1658K, 1572854 bytes
are fixed objects, that is, they're not subject to gc, they're not
java objects belonging to your application. Fixed objects are
memory holding class metadata such as bytecode, jitted code,
constant pools, utf8consts, etc.
This total includes 263 KB in memory for jitted bytecode.
This amount can be reduced if you use Kaffe's intr. Note, however,
that Kaffe frees the bytecode after jitting a method, so the
263 KB will not go down to zero, but instead will amount to the lesser
value occupied by the bytecode.
When using the interpreter, you also shouldn't have the 70432 bytes
in temporary memory for the jit engine.
Secondly, ca. 226K are taken up by jar file directory entries.
We could provide an interface to the VM that would close the jar
files once all classes have been loaded, this would free up that
amount of memory. This should work fine, even if some classes
are loaded after that: the jar file would simply be reopened.
Alternatively, load your classes from uncompressed unjarred
directories (may not be what you want to do on a small-dimensioned
machine.)
Third, note that how overhead for classes: approximately 967 KBytes
are used for class objects, jitcode, bytecode, and class metadata
such as constant pools.
This does not include an additional 152K for utf8 symbolic constants
(since these are shared between all classes, they're accounted for
separately)
Furthermore, note that this does not include the memory taken up
by objects to which static members of library classes refer.
I don't guarantee (yet) that this statistics is correct (in fact,
I know there's still some problems in the book keeping: there should
be at least 96K for threads (main + awt threads each take 32K,
gc + finalizer thread each take now 16K), but I think the ballpark
numbers are about right.
Furthermore, I should stress that this is for a completely
dynamically linked VM. The size of Kaffe itself is 8K, pretty
much everything is in shared libs. This is all a cost you might
need to add, depending on your configuration.
And if you're really in need of a low memory VM, you can always
ask Transvirtual for theirs.
- Godmar
(*) Unfortunately, Kaffe's appletviewer doesn't seem to do URL
quite yet, so I had to download it. Note it needs D[0123].gif
too.
[**] I guess I should fix that and gc before reporting a final
tally.