Dynamic Storage Allocation Techniques
(Submitted in the VIth semester Of B-Tech-CSE ) Session: 2015-16 Submitted By:Registration Number: 11205332 Roll Number: K2205, A-21 Name: Vangala Shravan Kumar
Submitted To: Cherry Khosla Date of Submission: 08 April 2015
ACKNOWLEDGEMENT:
First of all I would like to thank the Lovely Professional University, and take the opportunity to do this as a part of the B-TECH Many people have influenced the shape and content of this term paper, and many supported me through it. I express my sincere gratitude to “Cherry Khosla” for assigning me a term paper on “Dynamic Storage Allocation Techniques “. She has been an inspiration and role model for this topic. Her guidance and active support has made it possible to complete the assignment . I also would like to thank my Friends who have helped and encouraged me throughout the working of the project. Finally, I take this opportunity to acknowledge the services of the total team of publisher and everyone who collaborated in producing this work.
Vangala Shravan Kumar
1. Introduction Memory management is the act of managing computer memory at the system level. The essential requirement of memory management is to provide ways to dynamically allocate portions of memory to programs at their request, and free it for reuse when no longer needed. This is critical to any advanced computer system where more than a single process might be underway at any time . Several methods have been devised that increase the effectiveness of memory management. Virtual memory systems separate the memory addresses used by a process from actual physical addresses, allowing separation of processes and increasing the effectively available amount of RAM using Paging or swapping to secondary storage. The quality of the virtual memory manager can have an extensive effect on overall system performance. The task of fulfilling an allocation request consists of locating a block of unused memory of sufficient size. Memory requests are satisfied by allocating portions from a large pool of memory called the heap or free store. At any given time, some parts of the heap are in use, while some are "free" (unused) and thus available for future allocations. Several issues complicate the implementation, such as external fragmentation, which arises when there are many small gaps between allocated memory blocks, which invalidates their use for an allocation request. The allocator's metadata can also inflate the size of (individually) small allocations. This is often managed by chunking. The memory management system must track outstanding allocations to ensure that they do not overlap and that no memory is ever "lost" as a memory leak. Sometimes we do not release the user to create different variables according to their interest. It's a bit difficult to explain well, so give an example: imagine you want to do a text encoder, you do not know how
much space you will need in memory until the user gets the text, which can be a word or an entire book. The solution is to put a rookie char [10000], but even so we can be short, and if you have to decode a word, it goes up too much space. We need to change the variables and create them according to what happens, that is what I am discussing in this term paper.
Run Time Environment A program as a source code is merely a collection of text (code, statements etc.) and to make it alive, it requires actions to be performed on the target machine. A program needs memory resources to execute instructions. A program contains names for procedures, identifiers etc., that require mapping with the actual memory location at runtime. By runtime, we mean a program in execution. Runtime environment is a state of the target machine, which may include software libraries, environment variables, etc., to provide services to the processes running in the system. Runtime support system is a package, mostly generated with the executable program itself and facilitates the process communication between the process and the runtime environment. It takes care of memory allocation and de-allocation while the program is being executed.
2. Methodology used: Static Data Storage Allocation
Static allocation Temporary variables, including the one used to save the return address, were also assigned fixed addresses within the program. This type of storage assignment is called static allocation. Compiler allocates space for all variables (local and global) of all procedures at compile time.
No stack/heap allocation.
No overheads.
Ex: Fortran IV and Fortran 77.
Variable access is fast since addresses are known at compile time.
No recursion.
Dynamic Data Storage Allocation
Dynamic data storage allocation is necessary to preserve the previous values of any variables used by subroutine, including parameters, temporaries, return addresses, register save areas, storage allocation etc. It can be accomplished with a dynamic techniques. Compiler allocates space only for global variables at compile time. Space for variables of procedures will be allocated at run-time Stack/heap allocation. Ex: C, C++, Java, Fortran 8/9. Variable access is slow (compared to static allocation) since addresses are accessed through the stack/heap pointer. Recursion can be implemented.
Memory allocating using Stack: Stacks in computing architectures are regions of memory where data is added or removed in a last-in-first-out manner. In most modern computer systems, each thread has a reserved region of memory referred to as its stack. When a function executes, it may add some of its state data to the top of the stack; when the function exits it is responsible for removing that data from the stack. At a minimum, a thread's stack is used to store the location of function calls in order to allow return statements to return to the correct location, but
programmers may further choose to explicitly use the stack. If a region of memory lies on the thread's stack, that memory is said to have been allocated on the stack. Because the data is added and removed in a last-in-first-out manner, stack-based memory allocation is very simple and typically faster than heap-based memory allocation (also known as dynamic memory allocation). Another feature is that memory on the stack is automatically, and very efficiently, reclaimed when the function exits, which can be convenient for the programmer if the data is no longer required. If however, the data needs to be kept in some form, then it must be copied from the stack before the function exits. Therefore, stack based allocation is suitable for temporary data or data which is no longer required after the creating function exits. A thread's assigned stack size can be as small as a few dozen kilobytes. Allocating more memory on the stack than is available can result in a crash due to stack overflow. Some processors families, such as the x86, have special instructions for manipulating the stack of the currently executing thread. Other processor families, including PowerPC and MIPS, do not have explicit stack support, but instead rely on convention and delegate stack management to the operating system's application binary interface (ABI).
Memory allocating using Heap: The Heap is that portion of computer memory, allocated to a running application, where memory can be allocated for variables, class instances, etc. From a program's heap the OS allocates memory for dynamic use. Given a pointer to any one of the allocated blocks the OS can search in either direction to locate a block big enough to fill a dynamic memory allocation request.
Blocks of memory allocated on the heap are actually a special type of data structure consisting of (1) A pointer to the end of the previous block, (2) a pointer to the end of this block, (3) the allocated block of memory which can vary in size depending on its use
, (4) a pointer to the beginning of this block, and (5) a pointer to the next block.
Depending on the type of operating system there are two possible algorithms that can be implemented in order to locate a block of memory in the heap to allocate:
First-Fit - The needed amount of memory is allocated in the first block located in the heap that is big enough. This is faster but can result in greater fragmentation of the heap.
Best-Fit - All of the heap is searched and the needed amount of memory is allocated in the block where there is the least amount of memory left over. Slower but can result in less fragmentation.
Dynamic memory allocation is the practice of assigning memory locations to variables during execution of the program by explicit request of the programmer. Dynamic allocation is a unique feature to C (amongst high level languages). It enables us to create data types and structures of any size and length to suit our programs need within the program.
For example, to use arrays, dynamic memory allocation and use, eliminating the need to determine the size of the array at declaration time. What do I say it is that extra space does not have to. Areas that could use up to 1000 minutes, but you know, actually do not know how much is used, the worst case, might well end up without one. In such cases, to specify precisely the number of elements in the declaration is a
very difficult time. If too much waste of memory, and the less accessible outside of the array, may result in an error.
Dynamically allocated memory is freed when finished should not be used without. When released, this area no longer use that system to manage memory (OS) and I'll tell it to. When you exit the program without a release, essentially freed automatically. But I say with certainty, it should be freed by calling a dedicated function explicitly.
Finally, the dynamically allocated memory area, the area is secured in a location different from the usual definition of a variable. There is also the name depending on the role of memory space and just go. Used in the dynamic memory allocation area is called the heap. In contrast, the variables are usually allocated to the location of the stack. Variables are allocated on the heap, even if it was secured out of the scope, continues to exist. For example, in function, if you create a dynamic variable, but missing out the function and will continue to exist on the heap.
The functions malloc (), realloc (), calloc () and free (), the Library functions stdlib.h, malloc.h or are responsible for this task. All data are stored in the free store (heap), which is limited to 64k a stack in the beginning, this varies from machine. All variables were declared so far on the stack, now you tell me where to go, in an indirect way. In C we use malloc for allocating memory
The malloc() function dynamically allocates memory when required. This function allocates ‘size’ byte of memory and returns a pointer to the first byte or NULL if there is some kind of error.span> Format is as follows. void * malloc (size_t size); Specifies in bytes the size of the area you want to reserve the argument. It returns the address as the return value of the dynamically allocated area. In addition, returns NULL if it fails to secure the area. The failure to ensure that the situation is usually that is out of memory.
The return type is of type void *, also receive the address of any type. The fact is used as follows.
double * p = (double *) malloc (sizeof (double));
calloc() function The calloc function is used to allocate storage to a variable while the program is running. This library function is invoked by writing calloc(num,size).This function takes two arguments that specify the number of elements to be reserved, and the size of each element in bytes and it allocates memory block equivalent to num * size . The function returns a pointer to the beginning of the allocated storage area in memory. The important difference between malloc and calloc function is that calloc initializes all bytes in the allocation block to zero and the allocated memory may/may not be contiguous.
calloc function is used to reserve space for dynamic arrays. Has the following form. void * calloc (size_t n, size_t size); Number of elements in the first argument specifies the size in bytes of one element to the second argument. A successful partitioning, that address is returned, NULL is returned on failure. For example, an int array of 10 elements can be allocated as follows. int * array = (int *) calloc (10, sizeof (int));
Realloc() With the function realloc, you can change the size of the allocated area once. Has the following form. void * realloc (void * ptr, size_t size); The first argument specifies the address of an area that is currently allocated to the size in bytes of the modified second argument. Change the size, the return value is returned in re-allocated address space. Otherwise it returns NULL.
Free() function: how to release the reserved area, which will use the function free. Has also been declared in stdlib.h, which has the following form. void free (void * ptr); The argument specifies the address of a dynamically allocated area. You can then free up the space. Specify an address outside the area should not be dynamically allocated. Also, if you specify a NULL (or NULL if the same holds for a given pointer variable), the free function is guaranteed
to do nothing at all. In addition, if you try to re-release has already been freed space, so do not know what would be, and should never be.
By using new: In the C++ programming language, as well as in many C++-based languages, new is a language construct that dynamically allocates memory from free store and initialises the memory using the constructor. Except for a form called the "placement new", new attempts to allocate enough memory in free store for the new data. If successful, it initialises the memory and returns the address to the newly allocated and initialised memory. However if new cannot allocate memory in free store it will throw an exception of type std::bad_alloc . This removes the need to explicitly check the result of an allocation. A call to delete, which calls the destructor and returns the memory allocated by new back to free store, must be made for every call to new to avoid a memory leak. Syntax: p_var = new type_name;
3. Results: As a general rule, dynamic behaviour is troublesome in real time embedded systems. The two key areas of concern are determination of the action to be taken on resource exhaustion and nondeterministic execution performance. There are a number of problems with dynamic memory allocation in a real time system. The standard library functions (malloc() and free()) are not normally re-entrant(it is a function), which would be problematic in a multithreaded application. If the source code is available, this should be straightforward to rectify by locking resources using RTOS facilities (like a
semaphore). A more intractable problem is associated with the performance of malloc(). Its behaviour is unpredictable, as the time it takes to allocate memory is extremely variable. Such nondeterministic behaviour is intolerable in real time systems. Without great care, it is easy to introduce memory leaks into application code implemented using malloc() and free(). This is caused by memory being allocated and never being deallocated. Such errors tend to cause a gradual performance degradation and eventual failure. This type of bug can be very hard to locate. Memory allocation failure is a concern. Unlike a desktop application, most embedded systems do not have the opportunity to pop up a dialog and discuss options with the user. Often, resetting is the only option, which is unattractive. If allocation failures are encountered during testing, care must be taken with diagnosing their cause. It may be that there is simply insufficient memory available – this suggests various courses of action. However, it may be that there is sufficient memory, but not available in one contiguous chunk that can satisfy the allocation request. This situation is called memory fragmentation.
Memory Leak Detection: The potential for programmer error resulting in a memory leak when using partition pools is recognized by vendors of real time operating systems. Typically, a profiler tool is available which assists with the location and rectification of such bugs.
Real Time Memory Solutions Having identified a number of problems with dynamic memory behaviour in real time systems, some possible solutions and better approaches can be proposed.
4. Conclusions: C and C++ use memory in various ways, both static and dynamic. Dynamic memory includes stack and heap. Dynamic behaviour in embedded real time systems is generally a source of concern, as it tends to be non-deterministic and failure is hard to contain. Using the facilities provided by most real time operating systems, a dynamic memory facility may be implemented which is deterministic, immune from fragmentation and with good error handling. 5. References http://en.wikipedia.org/wiki http://www.cprogrammingexpert.com BELADY, L.A. A study of replacement algorithms for a virtual-storage computer http://www.cs.fsu.edu