๐ป Operating Systems - Processes, Threads, & Memory
Every line of code eventually competes for three things: CPU cycles, RAM, and IO bandwidth. A Programmer understands how the OS schedules these resources to avoid bottlenecks like thread starvation, memory leaks, and IO blocking.
๐งต Processes vs. Threads
Section titled โ๐งต Processes vs. ThreadsโThe fundamental units of execution.
- Process: An independent program in execution with its own isolated memory space (Stack, Heap, Data). Processes do not share memory by default; they use IPC (Inter-Process Communication).
- Thread: A lightweight unit within a process. Multiple threads share the same memory space (Heap) but have their own Stacks.
- Risk: Shared memory leads to Race Conditions. You must use synchronization primitives like Mutexes or Semaphores.
๐ง Memory Management
Section titled โ๐ง Memory ManagementโHow the OS provides a sandbox for your application.
- Virtual Memory: The OS gives each process the illusion of having a vast, contiguous block of memory, mapping โVirtual Addressesโ to physical RAM or disk (Swap).
- Stack vs. Heap:
- Stack: Fast, automatic allocation/deallocation. Used for local variables and function calls.
- Heap: Larger, manual (or Garbage Collected) allocation. Used for dynamic data that outlives a function call.
- Thrashing: Occurs when the system spends more time swapping data between RAM and Disk than executing code. This usually happens when the โWorking Setโ of your app exceeds available RAM.
๐ฅ I/O Models: Blocking vs. Non-Blocking
Section titled โ๐ฅ I/O Models: Blocking vs. Non-BlockingโIO is usually the slowest part of any system. How the OS handles it determines your applicationโs throughput.
- Blocking IO: The thread waits (sleeps) until the data is ready. Simple to write, but scales poorly (one thread per connection).
- Non-Blocking / Event-Driven: The thread asks for data and moves on. The OS notifies the app when data is ready (e.g.,
epollin Linux).- Real-world Example: This is the heart of Node.js and Goโs high concurrency.
โ๏ธ Concurrency Challenges
Section titled โโ๏ธ Concurrency ChallengesโContext Switching
Section titled โContext SwitchingโThe OS must save the state of a CPU core to swap one thread for another.
- The Cost: Context switching is expensive. If you have 10,000 threads on a 4-core CPU, the system will spend all its time switching and no time working.
- Solution: Use Thread Pools to limit the number of active threads or, in the case of Go language, use Green Threads/Goroutines which are managed by the language runtime instead of the OS.
User Space vs. Kernel Space
Section titled โUser Space vs. Kernel Spaceโ- Kernel Space: Where the OS core runs. It has full hardware access.
- User Space: Where your app runs.
- The โSystem Callโ Tax: Every time you read a file or send a network packet, your app must transition from User to Kernel space. Minimizing unnecessary system calls is a key performance optimization.
๐ ๏ธ Essential OS Concepts
Section titled โ๐ ๏ธ Essential OS Conceptsโ| Concept | What it is | Why it matters |
|---|---|---|
| Scheduler | The part of the OS that decides which thread runs next. | Understanding โPreemptionโ helps you debug why a task is being delayed. |
| File Descriptors | Integers representing open files/sockets. | โToo many open filesโ is a common production error when WebSockets or DB connections arenโt closed. |
| Deadlock | Two threads waiting for each otherโs locks. | Requires a โDetection and Recoveryโ or โPreventionโ strategy. |
๐ก Note: Donโt blame the Garbage Collector (GC) immediately for performance issues. Often, the problem is Memory Pressureโyour code is creating objects faster than the OS/Runtime can clean them up, forcing the GC to stop the world frequently.