| Each task has a heap which allows dynamic allocation using MAlloc() and Free(). For small allocations (<1024 bytes) when you free something, it is stored in a hash table to speed reallocation of the same size (just an array of linked lists for different sizes). Each task has it's own small-reallocation hash table. There is a medium-size hash table, shared by all tasks, which rounds to the nearest block (512 bytes) and stores sizes up to 128K. For larger chunks, the shared hash table goes by powers of two. When you specify a disk cache during recompilation, the size is rounded-up to a power of two. There is a function called MSize() which will return the true size of an allocated memory chunk and the disk cache code uses the true size, so nothing is wasted. Free'd small chunks stay in the task's hash table after a program runs. To return them to the system, kill the task CTRL-ALT-X or Kill() or Exit() and start a new task with CTRL-ALT-ESC or Spawn(). You can make a task that ends after running one program, using PopUp("") which Spawn()s a task and runs the code you place in "". It's pretty difficult to run-out of memory these days if you don't have multimedia graphics and sound. I have yet to run-out of memory, but I reboot a lot since I work on the operating system. (I have, of course, made bugs which use everything but that doesn't count.) Some memory allocations need to be independent of any particular task. Since the "Adam" task is always present, you can allocate such things off it's heap using AMAlloc(). The kernel allocates a few operating system structures from the Adam task's heap. The WORDSTAT feature has a large sparse matrix storing statistics to allow smart predictive auto-completion of text. You can recompile the kernel without WORDSTAT and save some memory. |
|