Tại sao phân bổ C++ (m) đầu tiên luôn là 72 KB?
Khám phá lý do tại sao cấp phát bộ nhớ C++ đầu tiên của bạn yêu cầu 72 KB thay vì số byte như mong đợi. Khám phá nội bộ malloc và các lớp quản lý bộ nhớ hệ điều hành được giải thích.
Mewayz Team
Editorial Team
Bí ẩn đằng sau việc phân bổ C++ đầu tiên của bạn
Bạn viết một chương trình C++ đơn giản. Một int mới duy nhất. Bốn byte. Bạn kích hoạt strace hoặc trình phân tích bộ nhớ yêu thích của mình và nó đây — quy trình của bạn vừa yêu cầu khoảng 72 KB từ hệ điều hành. Không phải 4 byte. Không phải 64 byte. Đầy đủ 72 KB. Nếu bạn đã từng nhìn chằm chằm vào con số đó và tự hỏi liệu công cụ của bạn có đang nói dối bạn hay không thì bạn không đơn độc. Hành vi có vẻ kỳ lạ này là một trong những câu hỏi thường gặp nhất trong số các nhà phát triển C++ lần đầu tiên đào sâu vào bên trong bộ nhớ và câu trả lời sẽ đưa chúng ta vào một hành trình hấp dẫn qua các lớp nằm giữa mã của bạn và phần cứng thực tế.
Điều gì xảy ra khi bạn gọi mới
Để hiểu con số 72 KB, bạn cần theo dõi chuỗi phân bổ đầy đủ. Khi mã C++ của bạn thực thi int mới, trình biên dịch sẽ chuyển lệnh đó thành lệnh gọi tới toán tử mới, lệnh này trên hầu hết các hệ thống Linux ủy quyền cho malloc từ glibc. Nhưng malloc không trực tiếp yêu cầu kernel cung cấp 4 byte bộ nhớ. Hạt nhân hoạt động trong các trang — thường là 4 KB trên x86_64 — và chi phí của một cuộc gọi hệ thống là rất lớn so với việc truy cập bộ nhớ đơn giản. Việc gọi brk() hoặc mmap() cho mỗi phân bổ riêng lẻ sẽ khiến bất kỳ chương trình không tầm thường nào bị dừng lại.
Thay vào đó, bộ cấp phát bộ nhớ của glibc — một triển khai có tên là ptmalloc2, bắt nguồn từ dlmalloc cổ điển của Doug Lea — hoạt động như một người trung gian. Nó yêu cầu các khối bộ nhớ lớn từ kernel trả trước, sau đó chia chúng thành các phần nhỏ hơn khi chương trình của bạn cần. Đây là lý do cơ bản khiến việc phân bổ 4 byte đầu tiên của bạn kích hoạt yêu cầu lớn hơn nhiều đối với hệ điều hành. Người cấp phát không bị lãng phí. Đó là chiến lược.
Phân tích 72 KB: Byte đi đâu
Chi phí phân bổ ban đầu đến từ một số thành phần riêng biệt mà bộ thực thi phải khởi tạo trước khi có thể trao cho bạn dù chỉ một byte bộ nhớ có thể sử dụng được. Việc hiểu từng thành phần sẽ giải thích tại sao con số lại nằm ở vị trí đó.
Đầu tiên, malloc của glibc khởi tạo đấu trường chính — cấu trúc sổ sách kế toán chính theo dõi tất cả các phân bổ trên luồng chính. Đấu trường này bao gồm siêu dữ liệu cho vùng heap, con trỏ danh sách tự do và cấu trúc thùng cho các kích cỡ phân bổ khác nhau. Bộ cấp phát mở rộng thời gian ngắt chương trình thông qua sbrk() và phần mở rộng ban đầu được điều chỉnh bởi một tham số bên trong có tên là M_TOP_PAD, mặc định là 128 KB phần đệm. Tuy nhiên, yêu cầu ban đầu thực tế được điều chỉnh để căn chỉnh trang và vị trí ngắt hiện có, điều này thường dẫn đến yêu cầu đầu tiên nhỏ hơn — thường đạt gần con số 72 KB đó trên quy trình mới bắt đầu.
💡 BẠN CÓ BIẾT?
Mewayz replaces 8+ business tools in one platform
CRM · Hóa đơn · Nhân sự · Dự án · Đặt chỗ · Thương mại điện tử · POS · Phân tích. Gói miễn phí vĩnh viễn có sẵn.
Bắt đầu miễn phí →Thứ hai, kể từ glibc 2.26, bộ cấp phát sẽ khởi tạo bộ đệm cục bộ theo luồng (tcache) trong lần sử dụng đầu tiên. Tcache chứa 64 thùng (một thùng cho mỗi lớp kích thước phân bổ nhỏ), mỗi thùng có khả năng chứa tối đa 7 khối được lưu trong bộ nhớ đệm. Bản thân tcache_perthread_struct tiêu tốn khoảng 1 KB, nhưng hành động khởi tạo nó sẽ kích hoạt thiết lập trường rộng hơn. Thứ ba, thời gian chạy C++ đã thực hiện phân bổ trước khi main() của bạn chạy — các hàm tạo tĩnh, khởi tạo bộ đệm iostream cho std::cout và bạn bè, cũng như thiết lập ngôn ngữ, tất cả đều góp phần vào dấu vết vùng nhớ heap ban đầu đó.
Hệ thống Đấu trường và Tại sao Phân bổ trước lại thông minh
Quyết định phân bổ trước một lượng lớn bộ nhớ thay vì yêu cầu nó từng phần không phải là một sự ngẫu nhiên khi triển khai. Đó là sự cân bằng kỹ thuật có chủ ý bắt nguồn từ kinh nghiệm lập trình hệ thống trong nhiều thập kỷ. Mọi lệnh gọi tới brk() hoặc mmap() đều liên quan đến việc chuyển ngữ cảnh từ không gian người dùng sang không gian kernel, sửa đổi ánh xạ bộ nhớ ảo của quy trình và cập nhật bảng trang tiềm năng. Trên phần cứng hiện đại, một lệnh gọi hệ thống tốn khoảng 100-200 nano giây — tầm thường nếu xét riêng lẻ, nhưng lại thảm khốc ở quy mô lớn.
Hãy xem xét một chương trình thực hiện 10.000 phân bổ nhỏ trong quá trình khởi tạo. Nếu không phân bổ trước, điều đó có nghĩa là 10.000 cuộc gọi hệ thống, tiêu tốn khoảng 1-2 mili giây chi phí thuần túy. Với công cụ cấp phát dựa trên đấu trường, lần phân bổ đầu tiên sẽ
Build Your Business OS Today
From freelancers to agencies, Mewayz powers 138,000+ businesses with 207 integrated modules. Start free, upgrade when you grow.
Create Free Account →Frequently Asked Questions
Tại sao phân bổ đầu tiên trong C++ lại lớn đến 72KB thay vì chỉ vài byte?
72KB không phải là để cấp phát cho biến int của bạn. Thay vào đó, đây là "bộ nhớ đệm" (heap) ban đầu mà trình quản lý bộ nhớ (như malloc trong glibc) yêu cầu từ hệ điều hành. Nó hoạt động như một nhóm bộ nhớ được dự trữ trước để chương trình có thể phân bổ các đối tượng nhỏ một cách nhanh chóng sau này mà không phải gọi hệ thống liên tục, giúp tối ưu hóa hiệu suất.
Con số 72KB có phải là cố định trên mọi hệ thống không?
Không, con số này có thể thay đổi. 72KB là giá trị phổ biến cho nhiều trình quản lý bộ nhớ trên Linux, nhưng nó phụ thuộc vào phiên bản thư viện C (glibc), nền tảng và các biến môi trường. Trên các hệ điều hành khác (như Windows) hoặc với các trình quản lý bộ nhớ khác, kích thước phân bổ ban đầu có thể sẽ khác. Đây là loại chi tiết mà các công cụ như Mewayz (với 207 module phân tích) có thể giúp bạn theo dõi.
Việc phân bổ này có lãng phí bộ nhớ không?
Không hẳn là lãng phí. Mặc dù không phải tất cả 72KB đều được sử dụng ngay lập tức, chiến lược này là một sự đánh đổi hợp lý. Bằng cách giảm số lần gọi hệ thống tốn kém, nó cải thiện đáng kể hiệu suất cho các lần cấp phát tiếp theo. Bộ nhớ dự trữ chưa dùng đến vẫn thuộc về tiến trình và sẽ được sử dụng cho các đối tượng bạn tạo ra sau này.
Tôi có thể kiểm soát hoặc thay đổi kích thước phân bổ ban đầu này không?
Có, nhưng nó thường không được khuyến nghị trừ khi bạn có nhu cầu đặc biệt. Bạn có thể sử dụng các biến môi trường (như MALLOC_TOP_PAD_ trên glibc) hoặc thay thế trình quản lý bộ nhớ hoàn toàn (ví dụ: tcmalloc, jemalloc). Tuy nhiên, việc tối ưu hóa này phức tạp. Đối với hầu hết nhà phát triển, việc sử dụng một công cụ phân tích như Mewayz (chỉ với $19/tháng) để hiểu hành vi bộ nhớ sẽ hiệu quả hơn.
Related Posts
Dùng Thử Mewayz Miễn Phí
Nền tảng tất cả trong một cho CRM, hóa đơn, dự án, Nhân sự & hơn thế nữa. Không cần thẻ tín dụng.
Nhận thêm các bài viết như thế này
Lời khuyên kinh doanh hàng tuần và cập nhật sản phẩm. Miễn phí mãi mãi.
Bạn đã đăng ký!
Bắt đầu quản lý doanh nghiệp của bạn thông minh hơn ngay hôm nay.
Tham gia 30,000+ doanh nghiệp. Gói miễn phí vĩnh viễn · Không cần thẻ tín dụng.
Sẵn sàng áp dụng vào thực tế?
Tham gia cùng 30,000+ doanh nghiệp đang sử dụng Mewayz. Gói miễn phí vĩnh viễn — không cần thẻ tín dụng.
Bắt đầu Dùng thử Miễn phí →Bài viết liên quan
Hacker News
288.493 yêu cầu – Cách tôi phát hiện ra lực lượng vũ phu XML-RPC từ tỷ lệ bộ nhớ đệm kỳ lạ
Apr 17, 2026
Hacker News
Bệnh viện ở trung tâm ổ dịch HIV ở trẻ em bị phát hiện tái sử dụng ống tiêm ở Pakistan
Apr 17, 2026
Hacker News
CadQuery là thư viện Python mã nguồn mở để xây dựng các mô hình CAD 3D
Apr 17, 2026
Hacker News
Hiển thị HN: Mô phỏng Spice → máy hiện sóng → xác minh bằng Mã Claude
Apr 17, 2026
Hacker News
Tất cả mọi thứ chúng tôi thích là một tâm lý
Apr 17, 2026
Hacker News
"Những kẻ khốn nạn, nói xấu tôi": Xenions của Goethe và Schiller (Phiên bản 1896)
Apr 17, 2026
Sẵn sàng hành động?
Bắt đầu dùng thử Mewayz miễn phí của bạn ngay hôm nay
All-in-one business platform. No credit card required.
Bắt đầu miễn phí →Dùng thử 14 ngày miễn phí · Không cần thẻ tín dụng · Hủy bất kỳ lúc nào