How to avoid memory fragmentation
Posted: 2021-12-11, 5:15:19
First, just had to say that I really am impressed with the amount of work that has gone into this whole project! Wow! I see a lot of really good and interesting ideas.
I read through the section in the manual on the various things that will help avoid memory fragmentation. Here is a list of the things that I understood and comments:
Stack - as noted, recursion makes this difficult if you cannot tell in advance how much you will have. It seems that recursion is not as heavily used as it once was so this may not be a huge problem, but it will make some algorithms more difficult. Many parsers and similar algorithms use recursion. This seems like a possibly onerous restriction.
DLLs etc - as long as it is clear that the CPU/ISA is a major break, I can follow this though it is not clear how the details work here, at least to me. How are things like ASRL going to be done? That is a relatively common scheme used to help avoid certain kinds of attacks. Is PIC the answer to that? As long as code is relatively static in size, this works. What about JIT systems like the JVM? Code is dynamically created.
Heap - this is where I run into problems. I do not follow the logic that you can come up with useful bounds on individual programs in the general case. Consider compilers, web browsers and database engines. These all have enormously different memory footprints depending on the inputs. Compiling "hello, World" takes a very different amount of memory than compiling the LLVM code base.
If you have very different heap sizes for different programs and they start and stop independently, then you will fragment memory. Existing paging systems work with almost all pages of the same size in order to make sure that all memory/address chunks are the same size and thus it is easy to reuse freed holes. I've followed some of the discussions, years ago, about the addition of huge pages to Linux for DB support and one of the pain points was making sure that you had sufficient contiguous physical address space to allocate a huge page. It is a lot easier to do it when the system boots and nothing has trampled all over RAM yet.
Is this what the end of the discussion of the thread "Implications of ForwardCom memory management approach" started by user JoeDuarte is aiming at solving? Toward the end of that thread a system of virtual addresses (with VIVT caches) was proposed. That sounds workable, at least if I understood the details correctly. However, even that will have some level of fragmentation as long as the basic unit of physical memory allocation is not always the same.
As I mentioned in the other thread, the Mill design uses separated memory translation and memory protection. It also uses a single virtual address space for all processes.
In that same thread, it was mentioned that with VIVT caches, you do not want to have more than one virtual address map to the same physical address. But isn't that exactly what happens when you create a shared memory block between two or more processes?
This leaves me confused. It sounds like having just a few memory region mappings is undermined by memory fragmentation and having variable length page/segments is undermined by fragmentation. VIVT caches seem like they might allow moving memory translation out of the fast path in the top level cache(s). How much of a problem is the problem I noted above?
Best,
Kyle
I read through the section in the manual on the various things that will help avoid memory fragmentation. Here is a list of the things that I understood and comments:
Stack - as noted, recursion makes this difficult if you cannot tell in advance how much you will have. It seems that recursion is not as heavily used as it once was so this may not be a huge problem, but it will make some algorithms more difficult. Many parsers and similar algorithms use recursion. This seems like a possibly onerous restriction.
DLLs etc - as long as it is clear that the CPU/ISA is a major break, I can follow this though it is not clear how the details work here, at least to me. How are things like ASRL going to be done? That is a relatively common scheme used to help avoid certain kinds of attacks. Is PIC the answer to that? As long as code is relatively static in size, this works. What about JIT systems like the JVM? Code is dynamically created.
Heap - this is where I run into problems. I do not follow the logic that you can come up with useful bounds on individual programs in the general case. Consider compilers, web browsers and database engines. These all have enormously different memory footprints depending on the inputs. Compiling "hello, World" takes a very different amount of memory than compiling the LLVM code base.
If you have very different heap sizes for different programs and they start and stop independently, then you will fragment memory. Existing paging systems work with almost all pages of the same size in order to make sure that all memory/address chunks are the same size and thus it is easy to reuse freed holes. I've followed some of the discussions, years ago, about the addition of huge pages to Linux for DB support and one of the pain points was making sure that you had sufficient contiguous physical address space to allocate a huge page. It is a lot easier to do it when the system boots and nothing has trampled all over RAM yet.
Is this what the end of the discussion of the thread "Implications of ForwardCom memory management approach" started by user JoeDuarte is aiming at solving? Toward the end of that thread a system of virtual addresses (with VIVT caches) was proposed. That sounds workable, at least if I understood the details correctly. However, even that will have some level of fragmentation as long as the basic unit of physical memory allocation is not always the same.
As I mentioned in the other thread, the Mill design uses separated memory translation and memory protection. It also uses a single virtual address space for all processes.
In that same thread, it was mentioned that with VIVT caches, you do not want to have more than one virtual address map to the same physical address. But isn't that exactly what happens when you create a shared memory block between two or more processes?
This leaves me confused. It sounds like having just a few memory region mappings is undermined by memory fragmentation and having variable length page/segments is undermined by fragmentation. VIVT caches seem like they might allow moving memory translation out of the fast path in the top level cache(s). How much of a problem is the problem I noted above?
Best,
Kyle