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.

Reply via email to