Vâng, quá trình tự nó phức tạp hơn một chút so với bạn đã viết. Một số bước bao gồm nhiều hơn một bước có thể nghĩ - ví dụ, bước 1 và cách nạp PE (và bản thân mscoree.dll được tải) bao gồm các bước bên trong bên trong.
Nhưng, tôi sẽ cố gắng trả lời câu hỏi của bạn. Chỉ cần thông báo rằng các câu hỏi của bạn khá lớn, vì vậy tôi đã cố gắng trả lời chúng một thời gian ngắn. Tuy nhiên, nếu bạn thực sự quan tâm đến điều đó, tôi khuyên bạn nên đọc CLR qua C# (bởi Richter). Ông thảo luận về quá trình tải trong chương đầu tiên, và có chương dành riêng cho bộ thu gom rác.
Ngoài ra còn có một số bài viết MSDN tốt về nguyên tắc cơ bản của bộ thu gom rác mà bạn có thể thấy thú vị.
Có bao nhiêu ngăn xếp, đống, chuỗi được tạo ?. Chủ đề có được tạo và thực thi mã trong tệp thi hành không?
Ứng dụng bảng điều khiển đơn giản (trống) sẽ có 3 luồng: chủ đề chính, chủ đề GC và trình kết thúc. tất nhiên, mỗi luồng có một ngăn xếp riêng (1MB mỗi luồng).
Số lượng heaps phụ thuộc vào loại GC bạn đang sử dụng. Nếu bạn đang sử dụng Workstation GC (mặc định) sẽ có 1 vùng được quản lý (với 2 phân đoạn, một cho đối tượng "bình thường" và một là phân đoạn heap đối tượng lớn).
Nếu bạn đang làm việc với Server GC, sẽ có 1 đống cho mỗi lõi logic có sẵn trong hệ thống (mỗi một trong số các đống có hai phân đoạn).
kích thước của bộ nhớ ban đầu được phân bổ là gì ?, người phân bổ bộ nhớ (OS hoặc CLR?)
Bộ nhớ ban đầu bao gồm nhiều hơn một yếu tố: có 1MB ngăn xếp cho mỗi thread , có kích thước của hình ảnh được tải trong quá trình (tùy thuộc vào ứng dụng của bạn), và có yếu tố "động" của kích thước - phân bổ bạn đang tạo trong ứng dụng của mình, điều này khiến GC tăng kích thước heap, và các đối tượng bạn không sử dụng nữa được làm sạch bởi GC và có thể khiến GC giải phóng bộ nhớ.
Nếu cần thêm bộ nhớ khi chạy exe, ai sẽ quyết định số lượng và thời điểm cấp phát bộ nhớ này?
Nếu bạn có ứng dụng bảng điều khiển đơn giản, bên trong trường hợp chính bạn tạo của lớp mới. Trong trường hợp đó, từ khóa "mới" (lệnh CIL "newobj") sẽ làm cho CLR tính toán số lượng bộ nhớ cần thiết.
Nếu có đủ bộ nhớ trong thế hệ 0 (nơi đối tượng mới được lưu trữ), sẽ không có cấp phát bộ nhớ bổ sung. Nếu không có đủ bộ nhớ, GC sẽ khởi động và sẽ gọi VirtualAlloc để cấp phát bộ nhớ cho đối tượng. Tham chiếu cho đối tượng mới được tạo, trong kịch bản đó, sẽ được lưu trên ngăn xếp.
Tất nhiên, nơi tham chiếu được lưu (ngăn xếp, đống, thanh ghi bộ xử lý) và nơi các đối tượng được cấp phát (ngăn xếp/đống) có thể thay đổi. Về cơ bản, điều đó phụ thuộc nếu chúng ta đang nói về phân bổ lớp hoặc cấu trúc, và bối cảnh của phân bổ (nếu nó là phương thức bên trong, như một trường trong lớp khác, một trường trong cấu trúc, vv). Nó cũng có thể thay đổi dựa trên nền tảng.
Nếu cần thêm bộ nhớ khi chạy exe, ai sẽ quyết định số lượng và thời điểm cấp phát bộ nhớ này?
Tất cả cấp phát bộ nhớ cho đối tượng mới được tạo trong quy trình của bạn được CLR quản lý (tất nhiên CLR sử dụng Windows API như VirtualAlloc và VirtualFree và cửa sổ quản lý bộ nhớ ảo).
Khi bạn sử dụng toán tử "mới" để tạo đối tượng mới sẽ được tạo trong vùng được quản lý, CLR tính toán kích thước cần thiết để phân bổ (kích thước của tất cả các trường + phí nhỏ cần thiết để khóa đối tượng ob và biết nó là loại gì) và xem nếu có không gian có sẵn trong heap được quản lý (trong thế hệ 0, CLR luôn giữ một con trỏ đến nơi các đối tượng mới sẽ được phân bổ). Nếu có, nó sẽ sử dụng nó. nếu không, nếu không đủ bộ nhớ thì bộ sưu tập rác sẽ bắt đầu, và đôi khi (phụ thuộc vào trạng thái bộ nhớ sau quá trình gc và một số thứ khác) VirtualAlloc sẽ được CLR gọi để cấp phát bộ nhớ nhiều hơn cho quá trình.
Điều gì sẽ xảy ra khi bạn đóng exe ?, CLR có chạy bất kỳ GC nào ngay trước khi dỡ Miền ứng dụng không? (đóng exe), hoặc hệ điều hành?
CLR chạy nhanh GC trước khi dỡ bất kỳ miền ứng dụng nào. Mục đích của GC nhanh này là để cho phép hoàn thành một cơ hội để chạy. Khi đóng quá trình, không cần CLR làm sạch bộ nhớ, vì hệ điều hành vẫn làm như vậy.
Hy vọng điều đó sẽ hữu ích.
Chỉ cần mua sách "CLR qua C#" hoặc đọc chuỗi blog "CLR Inside Out". Đây là cách quá rộng để trả lời đúng, và tôi khá chắc chắn mỗi câu hỏi của bạn đã được trả lời trước đó. – CodeCaster