12.6 Tweaking dynamic memory. 4tH 4tH Forth compiler
Reklaam
Reklaam
CHAPTER 12. STANDARD LIBRARIES 171
100 allocate abort" Out of memory" >r s" I’m a little crammed!" r@ place r@ count type cr r> free abort" Cannot free memory" r> free abort" Cannot free memory"
\ Second allocation
\ Store another string
\ Let’s print the string
\ Now free the first block
\ Now free the second block
Yes, that’s right: you feed ’FREE’ the address that ’ALLOCATE’ returned and it returns a flag. If it is a true flag, an error occurred; if not, everything is hunky dory. Let’s try to free it twice:
[needs lib/ansmem.4th]
600 allocate abort" Out of memory" >r s" Hello temporary world!" r@ place r@ count type cr r@ free abort" First attempt" r> free abort" Second attempt"
\ First allocation
\ Now store the string
\ Let’s print the string
\ Now let’s free the block
\ And try to free it again..
Yes, now 4tH terminated with the error message ”Second attempt”. You can not free a block twice..! But you can reallocate it if you happen to change your mind. You can increase or decrease its size, without losing any data. When the new block is too small to hold all the data, the data is truncated. Let’s see it in action:
[needs lib/ansmem.4th]
50 allocate abort" Out of memory" >r s" Hello temporary world!" r@ place r@ count type cr r> 100 resize abort" Out of memory" >r r@ count type cr r> free abort" Cannot free memory"
\ First allocation
\ Now store the string
\ Let’s print the string
\ Now resize the block
\ Here is your string again
\ Now free it
You’ll see that your precious string is still alright. Apart from a flag, ’RESIZE’ also returns the address of the reallocated block. If ’RESIZE’ fails, your original data is still alright, so in some circumstances you might want to save the old address.
12.6
Tweaking dynamic memory
You might find that 4tH doesn’t reserve much memory for dynamic allocation. Dynamic memory is allocated on the heap, which is 16 kB. You can increase it, but first you have to know how dynamic memory works. You can determine how much memory has been allocated by using the word ’ALLOCATED’:
CHAPTER 12. STANDARD LIBRARIES 172
[needs lib/ansmem.4th]
50 allocate abort" Out of memory" >r r@ . ." allocates " r@ allocated . ." bytes." cr
\ First allocation r> free abort" Cannot free memory" \ Now free it
And it will print something like:
768 allocates 64 bytes.
64 bytes? I thought we allocated 50 bytes! Let’s try another one:
[needs lib/ansmem.4th]
500 allocate abort" Out of memory" >r r@ . ." allocates " r@ allocated . ." bytes." cr
\ First allocation r> free abort" Cannot free memory" \ Now free it
This time it prints something like:
768 allocates 512 bytes.
As a matter of fact, ’ALLOCATED’ will always return multiples of 32 bytes. That is a consequence of how 4tH handles dynamic memory. 4tH divides dynamic memory into paragraphs . When you allocate memory, 4tH allocates as much paragraphs as it needs to provide you with the memory you requested. Then these paragraphs are marked as ’taken’.
This marking is done in the Heap Allocation Table, which is located in the Integer Segment.
Every paragraph is represented by a cell in the HAT.
You can fine-tune this mechanism by defining some constants before including ansmem.4th.
This will create a heap with 512 paragraphs of 256 bytes, which is 128 kB:
512 constant #paragraph
256 constant /paragraph
[needs lib/ansmem.4th]
500 allocate abort" Out of memory" >r
\ 512 paragraphs
\ each paragraph is 256 bytes
\ First allocation r@ . ." allocates " r@ allocated . ." bytes." cr r> free abort" Cannot free memory" \ Now free it
Try to keep the number of paragraphs low. 1024 seems like a nice upper limit. If you need that much memory, it is much better to handle it in larger chunks. This avoids fragmentation and keeps the time to search the HAT within acceptable limits.
If you’re using dynamic memory to manage e.g. linked lists, you can force a heap of cells by defining the pragma forcecellheap before you include ansmem.4th. You can even use the node structure definition to make it match a single paragraph, e.g.:
Laadi alla
Reklaam