Tải bản đầy đủ - 0 (trang)
CHƯƠNG 1: TÌM HIỂU CHUNG VỀ HEAP

CHƯƠNG 1: TÌM HIỂU CHUNG VỀ HEAP

Tải bản đầy đủ - 0trang

COM's IMalloc allocator (or CoTaskMemAlloc / CoTaskMemFree):

Chức năng sử dụng heap trên mỗi tiến trình mặ định. Tự động sử dụng bộ cấp

phát Component Object Model (COM) và các yêu cầu sử dụng heap cho mỗi

tiến trình.

C/C++ Run-time (CRT) allocator: Cung cấp malloc() và free() cũng

như các toán tử new và delete.

1.2. Phân loại heap

Mỗi tiến trình trong Windows có một heap được gọi là default heap. Các

tiến trình cũng có thể có nhiều dynamic heaps khác như mong muốn, chỉ đơn

giản bằng cách tạo và phá hủy chúng ngay lập tức. Hệ thống sử dụng heap

mặc định cho tất cả các hàm/chức năng quản lý bộ nhớ cục bộ và toàn cục, và

thư viện run-time C sử dụng heap mặc định để hỗ trợ các hàm/chức năng

malloc. Các hàm/chức năng bộ nhớ heap, cái mà biểu thị 1 heap riêng bởi

cách xử lý của nó, sử dụng dynamic heap.

Các heaps mặc định và động về cơ bản là giống nhau, nhưng heap mặc

định có đặc tính đặc biệt của việc nhận dạng được như là mặc định. Đây là

cách thư viện run-time C và hệ thống xác định heap để phân

bổ. Hàm GetProcessHeap trả về một heap mặc định để xử lý tiến trình. Vì

các hàm như GlobalAlloc hoặc malloc được thực thi trong ngữ cảnh của

luồng gọi chúng, chúng chỉ đơn giản gọi GetProcessHeap để lấy một đến

heap mặc định, và sau đó quản lý bộ nhớ một cách phù hợp.

1.3. Vai trò của heap

Hệ thống con Windows trên Windows NT cung cấp các chức năng quản

lý bộ nhớ cấp cao khiến cho các ứng dụng dễ dàng xây dựng các cấu trúc dữ

liệu động, cung cấp khả năng tương thích với các phiên bản trước của

Windows và tạo bộ đệm và bộ nhớ tạm thời cho các chức năng của hệ

thống. Các chức năng quản lý bộ nhớ này sẽ trả về các chốt xử lý và trỏ tới

các khối bộ nhớ được phân bổ trong thời gian chạy và được quản lý bởi một

thực thể được gọi là heap . Chức năng chính của heap là quản lý hiệu suất bộ

nhớ và không gian địa chỉ của một tiến trình cho một ứng dụng.

Ở một mức độ cao hơn, việc xem xét heap hồn tồn khơng ảnh hưởng

tới việc ứng dụng định làm gì với bộ nhớ của nó và địa chỉ rỗng. Tuy nhiên,

heap đã cung cấp một bộ các chức năng mạnh mẽ cho phép các nhà phát triển

bỏ qua một số chi tiết tốt hơn về tài nguyên hệ thống (như sự khác biệt giữa

bộ nhớ dành riêng, miễn phí và cam kết) để họ có thể biến sự chú ý của họ

thành một nhiệm vụ quan trọng hơn trong tay, của việc thực hiện các ứng

dụng của họ.

5



Trong Windows NT, heaps cung cấp một hạt nhỏ hơn cho kích thước của

bộ nhớ nhỏ nhất được phân bổ bộ nhớ hơn các chức năng quản lý bộ nhớ

ảo. Các ứng dụng thường cần phải phân bổ một số byte cụ thể để đáp ứng yêu

cầu tham số hoặc hoạt động như một bộ đệm tạm thời. Ví dụ, khi nạp một tài

nguyên chuỗi với chức năng LoadString , một ứng dụng chuyển một con trỏ

tới một bộ đệm nhận được tài nguyên chuỗi. Kích thước của bộ đệm phải đủ

lớn để chứa chuỗi và một terminator null. Nếu khơng có trình quản lý heap,

các ứng dụng sẽ buộc phải sử dụng các chức năng quản lý bộ nhớ ảo, phân bổ

ít nhất một trang bộ nhớ cùng một lúc.



1.4. Hành vi chung của heap

Trong khi heap cung cấp hỗ trợ để quản lý các khối nhỏ hơn của bộ nhớ,

nó khơng có gì hơn một đoạn bộ nhớ thực hiện trong hệ thống bộ nhớ ảo

Windows NT. Do đó, các kỹ thuật mà heap sử dụng để quản lý bộ nhớ dựa

trên các chức năng quản lý bộ nhớ ảo có sẵn cho heap. Bằng chứng này được

tìm thấy trong cách heaps tự thực hiện trong một tiến trình.

Ứng dụng mẫu của ProcessWalker (PW) khám phá mỗi thành phần trong

một tiến trình, bao gồm tất cả các heap của nó. PW xác định các heap trong

một quá trình và cho thấy dung lượng của bộ nhớ dành riêng và cam kết liên

quan đến một heap cụ thể. Giống như tất cả các vùng bộ nhớ khác trong một

tiến trình, vùng nhỏ nhất của bộ nhớ cam kết trong một heap là một trang

(4096 byte).

Điều này khơng có nghĩa là số lượng bộ nhớ nhỏ nhất có thể được phân

bổ trong heap là 4096 byte; thay vào đó, trình quản lý heap cam kết các trang

bộ nhớ nếu cần để đáp ứng các yêu cầu phân bổ cụ thể. Ví dụ, nếu một ứng

dụng phân bổ 100 byte thông qua một cuộc gọi tới hàm GlobalAlloc , trình

quản lý heap phân bổ bộ nhớ 100 byte trong vùng cam kết của nó cho yêu cầu

này. Nếu khơng có đủ bộ nhớ cam kết có sẵn tại thời điểm yêu cầu, trình quản

lý heap sẽ thực hiện cam kết một trang khác để làm cho bộ nhớ có sẵn.

Nếu một ứng dụng lặp đi lặp lại phân bổ các khối 100 byte bộ nhớ, heap

sẽ cam kết thêm một trang bộ nhớ cho mỗi 40 yêu cầu đầu tiên (40 * 100 byte

= 4000 byte). Khi yêu cầu 40 lần đầu tiên cho một đoạn 100 byte, heap

manager nhận ra rằng khơng có đủ bộ nhớ cam kết để đáp ứng yêu cầu, do đó

nó cam kết một trang khác của bộ nhớ và sau đó hồn thành việc phân bổ u

cầu. Bằng cách này, trình quản lý heap có trách nhiệm quản lý mơi trường bộ

nhớ ảo hoàn toàn minh bạch của ứng dụng.

Trong thực tế, dù vậy, heap manager yêu cầu bộ nhớ bổ sung để quản lý

bộ nhớ trong heap. Vì vậy, thay vì chỉ phân bổ 100 byte theo yêu cầu, nó

6



cũng phân bổ một số khơng gian để quản lý từng phần cụ thể của bộ

nhớ. Kiểu bộ nhớ và kích thước của phân bổ xác định kích thước của bộ nhớ

bổ sung này.

1.5. Các vấn đề chung về hiệu suất của heap

Đây là những trở ngại phổ biến nhất mà bạn gặp phải khi làm vi ệc

với heap:

•Chậm lại như là kết quả của hoạt động phân bổ. Nó chỉ đơn

giản mất một thời gian dài để phân bổ. Lý do có khả năng nhất

của sự chậm lại là các danh sách miễn phí khơng có các khối, và do

đó mã thời gian chạy allocator dành chu kỳ săn tìm cho một kh ối

lượng lớn hơn miễn phí hoặc phân bổ một khối tươi từ bộ cấp

phát back-end.

•Sự



chậm lại do hoạt động tự do. Các hoạt động tự do tiêu thụ

nhiều chu kỳ hơn, chủ yếu là nếu kết hợp lại được kích

hoạt. Trong q trình kết hợp, mỗi hoạt động tự do nên "tìm"

hàng xóm, kéo chúng ra để xây dựng một khối lớn hơn, và lắp l ại

khối lớn hơn vào danh sách miễn phí. Trong quá trình tìm kiếm,

bộ nhớ có thể bị xúc động theo thứ tự ngẫu nhiên, gây ra lỗi bộ

nhớ cache và hiệu năng làm chậm lại.



•Suy



thối như là kết quả của cuộc tranh luận heap. Sự tranh

luận xảy ra khi hai hoặc nhiều chủ đề thử truy cập vào dữ liệu

cùng một lúc và người ta phải đợi cho người kia hồn thành tr ước

khi có thể tiến hành. Cạnh tranh ln ln gây ra rắc rối; đó là vấn

đề lớn nhất mà một trong những gặp phải trên hệ thống đa. Một

ứng dụng hoặc DLL với khối lượng lớn sử dụng bộ nhớ sẽ chậm

lại khi chạy với nhiều luồng (và trên các hệ thống đa xử lý). Việc

sử dụng khóa đơn - giải pháp chung - có nghĩa là tất cả các hoạt

động sử dụng heap được tuần tự. Các serialization gây ra chủ đề

để chuyển đổi bối cảnh trong khi chờ khóa. Hãy tưởng tượng sự

suy thối do stop-and-go tại đèn pha nhấp nháy màu đỏ nhấp

nháy.

Sự ganh đua thường dẫn đến sự chuyển đổi ngữ cảnh của ch ủ

đề và quy trình. Bối cảnh chuyển mạch rất tốn kém, nhưng thậm

chí còn tốn kém hơn là mất dữ liệu từ bộ nhớ cache của bộ x ử lý

và xây dựng lại dữ liệu đó khi sợi được đưa vào cuộc sống sau đó.



•Suy



thối như là kết quả của tham nhũng đống. Tham nhũng xảy

ra khi ứng dụng khơng sử dụng khối heap đúng cách. Các tình

7



huống phổ biến bao gồm việc tăng gấp đôi hoặc sử dụng m ột

khối sau khi miễn phí, và các vấn đề rõ ràng về ghi đè v ượt quá

ranh giới khối.

•Chậm



lại như là một kết quả của allocs thường xuyên và

reallocs. Đây là một hiện tượng rất phổ biến khi bạn s ử dụng

ngôn ngữ kịch bản. Các chuỗi được phân bổ nhiều lần, phát triển

với sự phân bổ lại, và giải phóng. Đừng làm điều này. Hãy thử phân

bổ các chuỗi lớn, nếu có thể, và sử dụng bộ đệm. Một giải pháp

thay thế là giảm thiểu các hoạt động nối.



Sự ganh đua là vấn đề giới thiệu sự chậm lại trong phân bổ cũng

như hoạt động tự do. Lý tưởng nhất là chúng tơi muốn có một đống mà

khơng có tranh chấp và cấp phát nhanh / miễn phí. Than ơi, chẳng có

một đống mục đích chung như vậy, mặc dù nó có thể sẽ xảy ra trong

tương lai.

Trong tất cả các hệ thống máy chủ (như IIS, MSProxy, DatabaseStacks,

các máy chủ mạng, Exchange ...), khóa heap là m ột nút c ổ chai l ớn. Số bộ

vi xử lý càng lớn, thì sự tranh cãi càng tồi tệ.



8



CHƯƠNG 2: CƠ CHẾ QUẢN LÝ HEAP

Hầu hết các ứng dụng phân bổ các khối nhỏ hơn mức phân bổ tối thiểu

64-KB có thể bằng cách sử dụng các chức năng chi tiết trang như

VirtualAlloc và VirtualAllocExNuma. Việc phân bổ một khu vực rộng lớn

cho phân bổ tương đối nhỏ không phải là tối ưu từ cách sử dụng bộ nhớ và

quan điểm hiệu năng. Để giải quyết nhu cầu này, Windows cung cấp một

thành phần được gọi là heap manager, quản lý các khoản phân bổ bên trong

vùng bộ nhớ lớn hơn được dành riêng bằng chức năng phân bổ bộ nhớ theo

từng trang. Khả năng phân bổ trong trình quản lý heap tương đối nhỏ: 8 byte

trên các hệ thống 32-bit, và 16 byte trên các hệ thống 64-bit. Trình quản lý

heap đã được thiết kế để tối ưu hóa việc sử dụng và hiệu suất bộ nhớ trong

trường hợp các phân bổ nhỏ hơn.

Trình quản lý heap tồn tại ở hai nơi: Ntdll.dll và Ntoskrnl.exe. Các API hệ

thống con (chẳng hạn như các API của Windows heap) gọi các hàm trong

Ntdll, và các thành phần điều hành khác nhau và trình điều khiển thiết bị gọi

hàm trong Ntoskrnl. Các giao diện của nó (cố định đầu với Rtl) chỉ có sẵn để

sử dụng trong các thành phần Windows bên trong hoặc các trình điều khiển

thiết bị hạt nhân. Các giao diện Windows API đã được ghi lại để heap (tiền tố

với Heap) là chuyển tiếp đến các chức năng có trong Ntdll.dll. Ngồi ra, các

API kế thừa (cố định đầu bằng Local hoặc Global) được cung cấp để hỗ trợ

các ứng dụng Windows cũ, cũng được gọi chung là quản lý heap, sử dụng

một số giao diện đặc biệt để hỗ trợ hành vi kế thừa. Thời gian chạy C (CRT)

cũng sử dụng trình quản lý heap khi sử dụng các chức năng như malloc, free,

và nhà điều hành mới của C++. Các chức năng heap phổ biến nhất của

Windows là:

■ HeapCreate hoặc HeapDestroy: Tạo hoặc xóa, tương ứng, một đống.

Bản dự thảo ban đầu và kích thước cam kết có thể được xác định khi tạo.

■ HeapAlloc: Phân bổ một khối heap.

■ HeapFree: Giải phóng một khối được phân bổ trước đó với HeapAlloc.

■ HeapReAlloc: Thay đổi kích thước của một phân bổ hiện có (phát triển

hoặc co lại một khối hiện có).

■ HeapLock hoặc HeapUnlock: Các điều khiển loại trừ lẫn nhau vào các

hoạt động của heap.

■ HeapWalk: Khai báo các mục và các vùng trong một đống.



9



2.1. Những loại Heap

Mỗi tiến trình có ít nhất một heap: tiến trình heap mặc định. Heap mặc

định được tạo ra khi khởi động q trình và khơng bao giờ bị xóa trong suốt

q trình hoạt động của tiến trình. Mặc định có kích thước 1 MB, nhưng nó

có thể được làm lớn hơn bằng cách xác định kích thước bắt đầu trong tệp

hình ảnh bằng cách sử dụng cờ liên kết /HEAP. Kích thước này chỉ là dự trữ

ban đầu, tuy nhiên, nó sẽ tự động mở rộng khi cần thiết. (Bạn cũng có thể chỉ

định kích thước cam kết ban đầu trong tệp hình ảnh.)

Heap mặc định có thể được sử dụng một cách rõ ràng bởi một chương

trình hoặc ngầm sử dụng bởi một số chức năng Windows nội bộ. Một ứng

dụng có thể truy vấn heap quá trình mặc định bằng cách thực hiện cuộc gọi

đến hàm GetProcessHeap của Windows. Các quy trình cũng có thể tạo thêm

heap riêng với chức năng HeapCreate. Khi quá trình khơng còn cần một heap

riêng, nó có thể phục hồi không gian địa chỉ ảo bằng cách gọi HeapDestroy.

Một mảng với tất cả các heaps được duy trì trong mỗi q trình, và một sợi

có thể truy vấn chúng với các chức năng Windows GetProcessHeaps.

Một heap có thể quản lý phân bổ trong các vùng bộ nhớ lớn được lưu trữ

từ bộ quản lý bộ nhớ thông qua VirtualAlloc hoặc từ các đối tượng tệp ánh xạ

trên bộ nhớ ánh xạ trong khơng gian địa chỉ của tiến trình. Cách tiếp cận thứ

hai hiếm khi được sử dụng trong thực tế, nhưng nó phù hợp với các kịch bản

mà nội dung của các khối cần phải được chia sẻ giữa hai tiến trình hoặc giữa

một chế độ hạt nhân và một thành phần chế độ người dùng. Trình điều khiển

hệ thống con GUI Win32 (Win32k.sys) sử dụng một heap để chia sẻ GDI và

User các đối tượng với chế độ người dùng. Nếu một đống được xây dựng trên

đầu trang của vùng tệp được ánh xạ bộ nhớ, một số ràng buộc nhất định áp

dụng đối với thành phần có thể gọi hàm heap. Thứ nhất, các cấu trúc heap

bên trong sử dụng con trỏ, và do đó khơng cho phép remapping đến các địa

chỉ khác nhau trong các q trình khác. Thứ hai, q trình đồng bộ hóa qua

nhiều quá trình hoặc giữa một thành phần hạt nhân và q trình người dùng

khơng được hỗ trợ bởi các chức năng heap. Ngoài ra, trong trường hợp chia

sẻ heap giữa chế độ người dùng và chế độ hạt nhân, lập bản đồ chế độ người

dùng phải là chỉ đọc để ngăn chặn mã chế độ người dùng làm hỏng các cấu

trúc nội bộ của heap, dẫn tới sự sụp đổ của hệ thống. Trình điều khiển chế độ

hạt nhân cũng chịu trách nhiệm về việc không đưa bất kỳ dữ liệu nhạy cảm

nào vào một đống chia sẻ để tránh rò rỉ nó vào chế độ người dùng.

2.2. Cấu trúc của Heap Manager

Như trong hình dưới, cấu trúc của trình quản lý Heap gồm 2 lớp: lớp tùy

chỉnh front-end và lõi Heap. Lõi heap xử lý các chức năng cơ bản và phổ biến

nhất là usermode và kernel-mode triển khai Heap. Chức năng lõi bao gồm

10



Tài liệu bạn tìm kiếm đã sẵn sàng tải về

CHƯƠNG 1: TÌM HIỂU CHUNG VỀ HEAP

Tải bản đầy đủ ngay(0 tr)

×