Có một số khái niệm để trêu chọc nhau:
- chính ngôn ngữ lập trình Java, là ngôn ngữ lập trình văn bản,
- định dạng tệp byte & mã byte của Máy ảo Java , là mã hóa được biên dịch nhị phân của mã nguồn ngôn ngữ Java gốc và được sử dụng làm định dạng tệp trao đổi để lưu trữ, tải và chia sẻ mã đối tượng java,
- một triển khai Máy ảo Java cụ thể , có thể là một trình thông dịch, thay vào đó thường là một triển khai dựa trên JIT,
- JIT tạo mã máy chạy trực tiếp trên bộ xử lý phần cứng.
Java, ngôn ngữ lập trình , không định nghĩa kích thước khái niệm của các kiểu nguyên thủy bởi vì (không giống như C / C ++) không có sizeof
toán tử: kích thước không thể quan sát được thông qua các cấu trúc ngôn ngữ, vì vậy ngôn ngữ không cần xác định chúng.
Như @Ralf chỉ ra, ngôn ngữ Java xác định phạm vi của các kiểu nguyên thủy, rất phù hợp với người lập trình vì các phạm vi này có thể được quan sát thông qua các cấu trúc trong ngôn ngữ.
Ngôn ngữ xác định khả năng thiết bị cho phép điều tra kích thước của một đối tượng, nhưng (1) điều này đòi hỏi phải có thiết bị, (2) chỉ cung cấp ước tính và (3) yêu cầu này không áp dụng cho các kiểu nguyên thủy hoặc biến cục bộ.
JVM sử dụng một ô ngăn xếp 32 bit, được sử dụng để giữ các biến cục bộ, đối số phương thức và giá trị biểu thức. Các nguyên thủy nhỏ hơn 1 ô được đệm ra, các nguyên thủy lớn hơn 32 bit (dài và gấp đôi) lấy 2 ô
Trích dẫn đệm nói lên chi tiết về định dạng tệp lớp JVM, được sử dụng làm cơ chế trao đổi (khác với ngôn ngữ Java và cách triển khai JVM). Mặc dù những gì nó nói giữ cho máy trừu tượng và mã byte JVM, nhưng nó không nhất thiết phải giữ cho mã máy JIT'ed.
Báo giá đệm cũng hạn chế thảo luận về các biến / tham số / biểu thức cục bộ thường được phân bổ ngăn xếp (ví dụ: tự động hoặc tự động trong C / C ++) và không thảo luận về đối tượng / mảng.
Kích thước thực tế của các biến tự động như vậy hầu như không bao giờ là vấn đề (ví dụ về hiệu suất hoặc không gian).
Một phần, điều này là do các CPU phần cứng cơ bản hoạt động tự nhiên hơn trên các kích thước bit lớn hơn (như 32 hoặc 64) thay vì 1 bit. Ngay cả kích thước 8 hoặc 16 bit thường không nhanh hơn 32 và đôi khi xử lý 8 bit yêu cầu một lệnh bổ sung hoặc hai để làm việc với các thanh ghi rộng hơn của tập lệnh phần cứng.
Và một lý do khác là việc sử dụng các biến cục bộ bị hạn chế - chúng được sử dụng trực tiếp bởi mã và chỉ bởi mã, và do đó không thực sự chịu sự cố mở rộng - đặc biệt, so với các đối tượng và mảng, được sử dụng bởi các cấu trúc dữ liệu có khả năng ở bất kỳ quy mô nào .
(Chúng tôi có thể coi đệ quy là chia tỷ lệ của các biến cục bộ, do đó, một biến cục bộ lớn hơn trong thói quen đệ quy có nguy cơ tràn chồng sớm hơn.)
Tuy nhiên, kích thước của các đối tượng có thể quan trọng rất nhiều, nếu số lượng phiên bản cao và cũng có thể, kích thước của các phần tử mảng có thể quan trọng nếu có số lượng phần tử cao.
Điều đó có nghĩa là các kiểu dữ liệu primitiva thậm chí byte / char / short cũng mất 32 bit mặc dù kích thước của chúng được xác định là 8/16/16 bit?
Đối với người dân địa phương, có thể, có thể không phụ thuộc vào JIT.
Đối với các đối tượng, trong cơ chế tệp byte & mã byte JVM, các trường được truy cập trực tiếp bằng nhận dạng của chúng và không có khái niệm nào về "các ô" - trong khi đó có các biến (cục bộ và tham số).
Việc triển khai JVM (bao gồm JIT của nó) có tính linh hoạt để sắp xếp lại thứ tự trường trong khi thực hiện (ví dụ ở cấp mã máy) để hai trường 16 bit có thể chiếm cùng một từ 32 bit ngay cả khi chúng không được khai báo một cách ngẫu nhiên trong mã nguồn ; điều này làm giảm chi phí gây ra bởi phần đệm cần thiết để duy trì sự liên kết. Bất kỳ sự cân bằng, đệm và vị trí trường nào cũng rất quan tâm đến việc thực hiện JVM thay vì các mối quan tâm định dạng trao đổi JVM. Về lý thuyết, JIT có thể đóng gói booleans xuống một bit trong một mảng hoặc đóng gói 8 trường boolean riêng lẻ vào một byte trong một đối tượng. Đó hầu hết không phải là một lựa chọn triển khai JVM.