Search code examples
rebol3

How to interpret stats/show in Rebol 3


Wanted to make some profiling on a R3 script and was checking at the stats command. But what do these informations mean? How can it be used to monitor memory usage?

>> stats/show
Series Memory Info:
  node   size = 16
  series size = 20
       5 segs =  409640 bytes - headers
    4888 blks =  812448 bytes - blocks
    1511 strs =   86096 bytes - byte strings
       2 unis =   86016 bytes - unicode strings
       4 odds =   39216 bytes - odd series
    6405 used = 1023776 bytes - total used
       0 free /   14075 bytes - free headers / node-space

Pool[ 0]    8B   202/ 3328: 256 ( 6%) 13 segs,   26728 total
Pool[ 1]   16B   178/  512: 256 (34%)  2 segs,    8208 total
Pool[ 2]   32B   954/ 2560: 512 (37%)  5 segs,   81960 total
...
Pool[26]   64B     0/    0: 128 ( 0%)  0 segs,       0 total
Pools used 654212 of 1906200 (34%)
System pool used 497664
== 1023776

Solution

  • It shows the internal memory management information, not sure how useful it would be to the script.

    Anyway, here are some explanations about the memory pools.

    Most pools are for series (there is a dedicated pool for GOB!s, and some others if you're looking at Atronix source code), to make it simple, I will focus on series pools here.

    Internally, a series has a header and its data which is a chunk of contiguous memory. The header has the width and length info about the series. The data holds the actual content of the series. In R3, Series is used extensively to implement block!, port!, string!, object!, etc. So managing memory in R3 is almost managing (allocating and destroying) series. Because of the difference in the width and length of serieses, pools are introduced to reduce the fragmentation.

    When a new series is needed, the header is allocated in a special pool, and another pool is chosen for its data. The pool whose width is closed to the size of the series is chosen. E.g. a block with 3 elements will probably be allocated in a pool with width of 128-byte (on 32-bit systems, a block is a series with 4 (3 + 1 terminater) elements). As a pool could increase as the the program runs, it's implemented as a list of segments. New segments will be allocated and appended to the list as needed (but it's never released back to system).

    Another special pool is the system pool, which is chosen when the required memory is big. R3 doesn't actually manage this pool other than collecting some statistics.

    When it tries to collect garbage, it will sweep the root context, and mark everything that can be reachable, then it will go through the series header pool, and find out all unneeded serieses and destroy them.