Hãy cẩn thận về những gì loại mức sử dụng bộ nhớ mà bạn đang nói đến.
Mã được biên dịch thành C sử dụng bộ nhớ tương đối ít cho mã máy được biên dịch chính nó. Tôi có thể mong đợi Python bytecode cho một thuật toán đã cho thực sự nhỏ hơn mã C đã biên dịch cho một thuật toán tương tự, bởi vì các hoạt động bytecode của Python cao hơn nhiều nên thường có ít hơn để có được một điều nhất định. Nhưng một chương trình Python cũng sẽ có mã biên dịch của trình thông dịch Python trong bộ nhớ, đó là một chương trình khá lớn và phức tạp trong chính nó. Cộng với một chương trình Python điển hình sẽ có nhiều thư viện chuẩn trong bộ nhớ hơn là một chương trình C điển hình (và một chương trình C có thể loại bỏ tất cả các chức năng mà nó không thực sự sử dụng nếu nó được liên kết tĩnh và nếu nó được liên kết động thì nó sẽ chia sẻ mã được biên dịch với bất kỳ quá trình nào khác trong bộ nhớ sử dụng nó).
PyPy sau đó có trên đầu trang của mã máy này của trình biên dịch JIT, cũng như mã máy được tạo ra từ mã byte bytecode (không biến mất, nó cũng phải được giữ lại). Vì vậy, trực giác của bạn (rằng một hệ thống JITed "nên" tiêu thụ bộ nhớ một nơi nào đó giữa một ngôn ngữ biên soạn và một ngôn ngữ hoàn toàn được giải thích) là không chính xác anyway.
Nhưng trên đầu trang của tất cả những người bạn đã có bộ nhớ thực tế được sử dụng bởi các cấu trúc dữ liệu chương trình hoạt động trên. Điều này thay đổi vô cùng, và có rất ít để làm với việc chương trình được biên dịch trước thời hạn, hoặc giải thích, hoặc giải thích và JITed.Một số tối ưu hóa trình biên dịch sẽ làm giảm việc sử dụng bộ nhớ (cho dù chúng được áp dụng trước thời hạn hoặc chỉ trong thời gian), nhưng nhiều người thực sự giao dịch sử dụng bộ nhớ để đạt được tốc độ. Đối với các chương trình xử lý bất kỳ lượng dữ liệu nghiêm trọng nào, nó sẽ hoàn toàn lùn bộ nhớ được sử dụng bởi chính mã đó.
Khi bạn nói:
Thay vào đó một chương trình JIT'ed (như PyPy) tiêu thụ nhiều lần bộ nhớ hơn tương đương với chương trình giải thích (ví dụ như Python). Tại sao?
Bạn đang nghĩ đến chương trình nào? Nếu bạn đã thực sự thực hiện bất kỳ so sánh, tôi đoán từ câu hỏi của bạn rằng họ sẽ được giữa PyPy và CPython. Tôi biết nhiều cấu trúc dữ liệu của PyPy thực sự nhỏ hơn CPython, nhưng lại không liên quan gì đến JIT.
Nếu sử dụng bộ nhớ chi phối của chương trình là mã, thì trình biên dịch JIT sẽ bổ sung thêm chi phí bộ nhớ khổng lồ (cho trình biên dịch và mã được biên dịch) và không thể làm gì nhiều để "giành lại "sử dụng bộ nhớ thông qua tối ưu hóa. Nếu sử dụng bộ nhớ chiếm ưu thế là cấu trúc dữ liệu chương trình, thì tôi sẽ không ngạc nhiên khi thấy PyPy sử dụng bộ nhớ ít hơn đáng kể so với CPython, cho dù JIT có được bật hay không.
Không thực sự là câu trả lời đơn giản cho "Tại sao?" bởi vì các câu trong câu hỏi của bạn không thẳng thắn. Hệ thống nào sử dụng nhiều bộ nhớ hơn phụ thuộc vào nhiều yếu tố; sự hiện diện hay vắng mặt của trình biên dịch JIT là một yếu tố, nhưng nó không phải luôn luôn có ý nghĩa.
Mọi người đều nói về JIT là nguyên nhân của việc sử dụng bộ nhớ tăng lên trong Pypy, nhưng đó không phải là toàn bộ câu chuyện. Mặc dù một số cấu trúc bộ nhớ của Pypy nhỏ gọn hơn (danh sách tất cả các int), Pypy có nhiều bộ thu gom rác có thể được sử dụng với nó và chắc chắn sẽ ảnh hưởng đến lượng bộ nhớ đang sử dụng. Bộ thu gom rác mặc định hiện tại trong Pypy không tính toán tham chiếu vì lợi ích của tốc độ. Do đó, các đối tượng có thể vẫn còn trong bộ nhớ lâu hơn trong CPython và do đó các chương trình có thể có một bộ nhớ lớn hơn trong Pypy. –