about
10/14/2022
Program Execution
BasicBites - Program Execution
Processes, memory, native, managed, resources
Processes
HANDLE HeapCreate(DWORD flOptions, SIZE_T dwInitialSize, SIZE_T dwMaximumSize);
Most of a program's API calls are handled by the programming lanaguage's standard libraries so the
program doesn't need to know about these calls.
- Static memory holding code and global data
- Stack memory is allocated when the program's thread of execution enters a new scope, delineated by "{...}", and deallocated when execution leaves the scope. For native code this scratch-pad memory holds function parameters and all local objects declared within the scope. For managed code stack memory holds values for value types and references to heap-based objects for managed types. This is true for both function parameters and instances declared within the current scope.
-
Heap memory allocated with calls to
new . Native code deallocates heap-based instances with calls todelete . Managed code uses the services of a garbage collector to defer deallocation for latter analysis to ensure that no references to the instance remain.
Native vs. Managed Code
Native Types
-
types with contiguous memory footprints:
primitive types, native arrays, and structs without pointer or reference members
-
types with non-contiguous memory footprints:
most library and user-defined types, like String.
- pointers and references to either of the above
Managed Types
-
Value types
primitives, native arrays, and structs
implement Copy type behavior described in Part 1 -
Managed reference types
all user-defined types
implement Reference type behavior of Part 1. -
Managed handles (references)
support access and resource management
Resource Management:
Consequences:
C++ - Native Code | |
---|---|
Source code | Compiles to native code executed by its process |
Objects | stored in function's stack frame unless explicity placed in heap or static memory |
Object management | provided by program code, e.g., creation, deallocation, exception handling |
Types | Language enables user-defined objects to behave like primitive types, e.g., value behavior, through use of constructors and assignment operators. |
Moves | C++ provides move constructors but does not enforce single ownership, allowing use of source after move, possibly resulting in undefined behavior. |
Pros and Cons | excellent performance, requires care to avoid paths to undefined behavior |
Rust - Native Code | |
Source code | Compiles to native code executed by its process |
Objects | stored in function's stack frame unless explicity placed in heap with Box |
Object management | provided by program code and library, e.g., creation, deallocation, error handling |
Types | Rust has two categories of types: Copy types and Move types. Copy types have value behavior. Move types transfer ownership when assigned or passed by value. |
Moves | Rust treats all types that are not copy (satisfy the Copy trait) as moves. It enforces single ownership so source becomes invalid after move. |
Pros and Cons | excellent performance and safety. Initially hard to build due to safety constraints, but once built is very likely to have correct implementation. |
C# - Managed Code | |
Source code | Compiles to byte-code, jitted and executed by its process's virtual machine |
Object storage | object handles stored in function's stack, pointing to instances stored in heap |
Object management | provided by virtual machine using garbage collector and VM events |
Types | Types are either value or reference types, with quite different behavior |
Moves | C# does not provide move operations. |
Pros and Cons | promotes safety at the expense of performance and initial latency |