I'm looking into the memory model a little more and am struggling with understanding how many heap's exist in a process.
So if we have 1 process with 5 threads in it, am I correct in saying that we'd have 5 stacks and 1 heap?
If so, can the threads access one another's stacks (or is this exactly why they have separate Stacks, to prevent corruption), and if there's just 1 heap, then obviously they all access this heap, hence the need for locking with multiple threads? Am I understanding this correctly?
Overview. Stack memory is the space allocated for a process where all the function calls, primitive data types (int, double, etc.) and local and reference variables of the functions are stored. On the other hand heap memory is used to store the objects that are created during the execution of a Java program.
Stack and a Heap ? Stack is used for static memory allocation and Heap for dynamic memory allocation, both stored in the computer's RAM . Variables allocated on the stack are stored directly to the memory and access to this memory is very fast, and it's allocation is dealt with when the program is compiled.
The Heap Space contains all objects are created, but Stack contains any reference to those objects. Objects stored in the Heap can be accessed throughout the application. Primitive local variables are only accessed the Stack Memory blocks that contain their methods.
Yes, each thread has its own stack. That's a hard necessity, the stack keeps track of where a method returns after it finishes, it stores the return address. Since each thread executes its own code, they need their own stack. Local variables and method arguments are stored there too, making them (usually) thread-safe.
The number of heaps is a more involved detail. You are counting 1 for the garbage collected heap. That's not entirely correct from an implementation point of view, the three generational heap plus the Large Object Heap are logically distinct heaps, adding that up to four. This implementation detail starts to matter when you allocate too much.
Another one that you can't entirely ignore in managed code is the heap that stores static variables. It is associated with the AppDomain, static variables live as long as the AppDomain lives. Commonly named "loader heap" in .NET literature. It actually consists of 3 heaps (high frequency, low frequency and stub heap), jitted code and type data is stored there too but that's getting to the nitty gritty.
Further down the ignore list are the heaps used by native code. Two of them are readily visible from the Marshal class. There's a default process heap, Windows allocates from it, so does Marshal.AllocHGlobal(). And there's a separate heap where COM stores data, Marshal.AllocCoTaskMem() allocates from it. Lastly any native code you interop with will have its own heap for its runtime support. The number of heaps used by that kind of code is bounded only by the number of native DLLs that get loaded into your process. All of these heaps exist, you barely ever deal with them directly.
So, 10 heaps minimum.
In short, yes.
All threads in a process share the same heap, so they can exchange data. Each thread has it's own stack that relates to the current code execution on this thread.
A very good resource on threading is here: http://www.albahari.com/threading/
A thread is analogous to the operating system process in which your application runs. Just as processes run in parallel on a computer, threads run in parallel within a single process. Processes are fully isolated from each other; threads have just a limited degree of isolation. In particular, threads share (heap) memory with other threads running in the same application. This, in part, is why threading is useful: one thread can fetch data in the background, for instance, while another thread can display the data as it arrives.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With