What is the difference between AppDomain, Assembly, Process, and a Thread?
One of the biggest advantage of CLR's JIT compiler is - it prevents overlapping of processes' virtual address space. For example, if process 1 is spawned and the CLR (MScorEE.dll) is managing the execution of a managed assembly (.exe or .dll) within that process, then the JIT compiler will make sure that the virtual address space allocated to this process will not collide or overlap with the other adjacent processes. Having this advantage, it is now possible to re-use the single process for more than one managed code execution! Each managed code execution will have its own AppDomain and more than AppDomains could be part of a single process. This is what used by IIS and SQL Server (single process, many AppDomains).
Assembly is an abstract term that represents a single, re-usable component of managed code. Assembly consists of Metadata (PE32 or PE32+ header + IL header) and IL instructions. CLR's JIT compiler compiles and converts ILs of assembly into a machine specific instruction set, based on the processor and it's architecture (x86 or x64).
Process is what OS uses to facilitate the execution of a program. A process is a "RAM representation" of a program that has address space which consists of stack, heap, static and code region. Each process has a unique process Id associated with it.
Thread is a light weight process. A process has at least one thread (i.e. main thread) and depending upon the parallelism OS can create multiple threads within a single process and context-switch among them to support faster program execution. Threads can share some memory regions within a process.