Do Different Programs Gets Their Memory from a Common Heap or from a Separate Heap

Do different programs gets their memory from a common heap or from a separate heap?

  1. There is no common heap in the libc sense - this would violate process protection and virtual memory rules. Each process maintains its own heap. The kernel (with the help of the MMU in the processor) maintains the virtual memory tables which map virtual addresses to real memory.

  2. Static libraries are nothing more than linking code at compile time - there is no run time concept of a static library. It is one and the same as the process, and will use its heap.

Is heap memory per-process? (or) Common memory location shared by different processes?

On almost every system currently in use, heap memory is per-process. On older systems without protected memory, heap memory was system-wide. (In a nutshell, that's what protected memory does: it makes your heap and stack private to your process.)

So in your example code on any modern system, if the process terminates before delete pIntPtr is called, pIntPtr will still be freed (though its destructor, not that an int has one, would not be called.)

Note that protected memory is an implementation detail, not a feature of the C++ or C standards. A system is free to share memory between processes (modern systems just don't because it's a good way to get your butt handed to you by an attacker.)

What and where are the stack and heap?

The stack is the memory set aside as scratch space for a thread of execution. When a function is called, a block is reserved on the top of the stack for local variables and some bookkeeping data. When that function returns, the block becomes unused and can be used the next time a function is called. The stack is always reserved in a LIFO (last in first out) order; the most recently reserved block is always the next block to be freed. This makes it really simple to keep track of the stack; freeing a block from the stack is nothing more than adjusting one pointer.

The heap is memory set aside for dynamic allocation. Unlike the stack, there's no enforced pattern to the allocation and deallocation of blocks from the heap; you can allocate a block at any time and free it at any time. This makes it much more complex to keep track of which parts of the heap are allocated or free at any given time; there are many custom heap allocators available to tune heap performance for different usage patterns.

Each thread gets a stack, while there's typically only one heap for the application (although it isn't uncommon to have multiple heaps for different types of allocation).

To answer your questions directly:

To what extent are they controlled by the OS or language runtime?

The OS allocates the stack for each system-level thread when the thread is created. Typically the OS is called by the language runtime to allocate the heap for the application.

What is their scope?

The stack is attached to a thread, so when the thread exits the stack is reclaimed. The heap is typically allocated at application startup by the runtime, and is reclaimed when the application (technically process) exits.

What determines the size of each of them?

The size of the stack is set when a thread is created. The size of the heap is set on application startup, but can grow as space is needed (the allocator requests more memory from the operating system).

What makes one faster?

The stack is faster because the access pattern makes it trivial to allocate and deallocate memory from it (a pointer/integer is simply incremented or decremented), while the heap has much more complex bookkeeping involved in an allocation or deallocation. Also, each byte in the stack tends to be reused very frequently which means it tends to be mapped to the processor's cache, making it very fast. Another performance hit for the heap is that the heap, being mostly a global resource, typically has to be multi-threading safe, i.e. each allocation and deallocation needs to be - typically - synchronized with "all" other heap accesses in the program.

A clear demonstration:
Sample Image

Image source: vikashazrati.wordpress.com

Is heap related to process in C?

You are correct, heap memory is per process. However, all processes on the same system allocate memory from the same fixed pool, which is limited to the physical memory of your system plus the swap file on virtual memory systems. That is why if one process holds on to the memory that it does not need, it may starve of memory another process on the same computer.

On systems with virtual memory this does not necessarily mean that other processes will run out of memory, though: it means that getting more memory for these other processes would require swapping other processes out of memory. It may be your leaking process or some other process that must be swapped.

On systems without virtual memory management leaking memory in one process would lead to other processes being unable to allocate memory at all.

Does Each program has its own separate segments (code, stack, data) in memory?

This depends on two things:

  • Your deployment architecture
  • Your OS that runs your process

If you are running on x86 on common mainstream Linux, Windows, BSD then

  • each process has it's own private virtual RAM
  • All segments text (code), heap, data are in the same logical address space (virtual RAM segment)

Historically x86 was designed with the ability to support segmented memory, but OSes never made use of it and support for it was initially dropped in AMD64. Though recent Processors support it again for use in virtualisation and Hypervisors. Userland applications are commonly deployed without segmentation today.

Do threads have a distinct heap?

No. All threads share a common heap.

Each thread has a private stack, which it can quickly add and remove items from. This makes stack based memory fast, but if you use too much stack memory, as occurs in infinite recursion, you will get a stack overflow.

Since all threads share the same heap, access to the allocator/deallocator must be synchronized. There are various methods and libraries for avoiding allocator contention.

Some languages allow you to create private pools of memory, or individual heaps, which you can assign to a single thread.

Do (statically linked) DLLs use a different heap than the main program?

DLLs / exes will need to link to an implementation of C run time libraries.

In case of C Windows Runtime libraries, you have the option to specify, if you wish to link to the following:

  1. Single-threaded C Run time library (Support for single threaded libraries have been discontinued now)
  2. Multi-threaded DLL / Multi-threaded Debug DLL
  3. Static Run time libraries.
  4. Few More (You can check the link)

Each one of them will be referring to a different heap, so you are not allowed pass address obtained from heap of one runtime library to other.

Now, it depends on which C run time library the DLL which you are talking about has been linked to. Suppose let's say, the DLL which you are using has been linked to static C run time library and your application code (containing the main function) has linked to multi-threaded C Runtime DLL, then if you pass a pointer to memory allocated in the DLL to your main program and try to free it there or vice-versa, it can lead to undefined behaviour. So, the basic root cause are the C runtime libraries. Please choose them carefully.

Please find more info on the C run time libraries supported here & here

A quote from MSDN:

Caution Do not mix static and dynamic versions of the run-time libraries. Having more than one copy of the run-time libraries in a process can cause problems, because static data in one copy is not shared with the other copy. The linker prevents you from linking with both static and dynamic versions within one .exe file, but you can still end up with two (or more) copies of the run-time libraries. For example, a dynamic-link library linked with the static (non-DLL) versions of the run-time libraries can cause problems when used with an .exe file that was linked with the dynamic (DLL) version of the run-time libraries. (You should also avoid mixing the debug and non-debug versions of the libraries in one process.)

heap overflow affecting other programs

So my question is whether the memory for heap is shared with other programs?

Physical memory (RAM) is a resource that is shared by all processes. The operating system makes decisions about how much RAM to allocate to each process and adjusts that over time.

If not, other programs should not have affected. Is OS is not allocating certain amount of memory at the time of execution?

At the time the program starts executing, the operating system has no idea how much memory the program will want or need. Instead, it deals with allocations as they happen. Unless configured otherwise, it will typically do everything it possibly can to allow the program's allocation to succeed because presumably there's a reason the program is doing what it's doing and the operating system won't try to second guess it.

What is a Memory Heap?

Presumably you mean heap from a memory allocation point of view, not from a data structure point of view (the term has multiple meanings).

A very simple explanation is that the heap is the portion of memory where dynamically allocated memory resides (i.e. memory allocated via malloc). Memory allocated from the heap will remain allocated until one of the following occurs:

  1. The memory is free'd
  2. The program terminates

If all references to allocated memory are lost (e.g. you don't store a pointer to it anymore), you have what is called a memory leak. This is where the memory has still been allocated, but you have no easy way of accessing it anymore. Leaked memory cannot be reclaimed for future memory allocations, but when the program ends the memory will be free'd up by the operating system.

Contrast this with stack memory which is where local variables (those defined within a method) live. Memory allocated on the stack generally only lives until the function returns (there are some exceptions to this, e.g. static local variables).

You can find more information about the heap in this article.

Concurrent Programming, Stacks and Heaps in C/C++

  1. Global variables are allocated in a static section of memory that's laid out at compile time. The values are initialized during startup before main is entered. The initialization may, of course, allocate on the heap (i.e. a statically allocated std::string will have the structure itself sit in the statically laid out memory, but the string data it contains is allocated on the heap during startup). These things are deleted during normal program shutdown. You can't free them before then, if you wish to, you may want to wrap the value in a pointer, and initialize the pointer on program startup.

  2. The heap is managed by an allocator library. There's one that comes with the C runtime, but also custom ones like tcmalloc or jemalloc that you can use in place of the standard allocator. These allocator get large pages of memory from the OS using system calls, and then give you portions of these pages when you call malloc. The organization of the heap is somewhat complex and varies between allocators, you can look up how they work on their websites.

  3. Yes-ish. Though you can use library functions like alloca to make a chunk of space on the stack, and use that for whatever you want.

  4. Each process has a separate memory space, that is, it thinks it is all alone and no other process exists. Generally the OS will give you more memory if you ask for it, but it can also enforce limits (like ulimit on linux), at which time it can refuse to give you more memory. Fragmentation isn't an issue for the OS because it gives memory in pages. However fragmentation in your process may cause your allocator to ask for more pages, even if there's empty space.

  5. Yes.

  6. Yes, however there's generally OS specific ways to create shared-memory regions that multiple processes can access.

  7. stack overflows doesn't crash anything itself, it causes memory values to be written in places that may hold other values, thus corrupting it. Acting on corrupted memory causes crashes. When your process accesses unmapped memory (see note below) it crashes, not just a thread, but the whole process. It would not affect other processes since their memory spaces are isolated. (This is not true in old operating systems like Windows 95, where all processes shared the same memory space).

  8. In C++, stack-allocated objects are created when the block is entered, and destroyed when the block is exited. The actual space on the stack may be allocated less precisely though, but the construction and destruction will take place at those particular points.

  9. The stack pointer on x86 processes can be arbitrarily manipulated. It's common for compilers to generate code that simply add the amount of space to the stack pointer, and then set the memory for values on the stack, instead of doing a bunch of push operations.

  10. The stacks and heap of the process all live in the same memory space.

An overview of how memory is organized may be helpful:

  • You have physical memory which the kernel sees.
  • The kernel maps pages of physical memory to pages of virtual memory when a process asks for it.
  • A process operates in its own virtual memory space, ignorant of other processes on the system.
  • When a process starts, it puts sections of the executable (code, globals, etc) into some of these virtual memory pages.
  • The allocator requests pages from the process in order to satisfy malloc calls, this memory constitutes the heap.
  • when a thread starts (or the initial thread for the process), it asks the OS for a few pages that form the stack. (You can also ask your heap allocator, and use the space it gives you as a stack).
  • When the program is running, it can freely access to all memory in its address space, heap, stack, whatever.
  • When you attempt to access a region of your memory space that is not mapped, your program crashes. (more specifically, you get a signal from the OS, which you can choose to handle).
  • Stack overflows tend to cause your programs to access such unmapped regions, which is why stack overflows tend to crash your program.


Related Topics



Leave a reply



Submit