kích thước boolean không được xác định trong java: tại sao?


10

Tôi thấy kích thước của boolean không được xác định. Dưới đây là hai tuyên bố tôi thấy ở kích thước dữ liệu nguyên thủy java

không được xác định chính xác

Giải thích thêm nói

boolean đại diện cho một chút thông tin, nhưng "kích thước" của nó không phải là thứ được xác định chính xác.

Câu hỏi xuất hiện trong đầu tôi là tại sao boolean trong java không thể được biểu diễn bằng 1 bit (hoặc 1 byte nếu byte là biểu diễn tối thiểu)?

Nhưng tôi thấy nó đã được trả lời tại /programming/1907318/why-is-javas-boolean-primitive-size-not-d xác định nơi nó nói

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 ô

Đ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?

Ngoài ra chúng ta có thể nói kích thước boolean sẽ là 32 bit trên cpu 32 bit và 64 bit trên cpu 64 bit không?



Does it mean even byte/char/short primitiva data types also take 32 bit though their size is defined as 8/16/16 bit ?-- Đúng.
Robert Harvey

Also can we say boolean size will be 32 bit on 32 bit cpu and 64 bit on 64 bit cpu ?- Không. Kích thước được định nghĩa bởi JVM.
Robert Harvey

@RobertHarvey Nếu các kiểu dữ liệu nguyên thủy byte / char / short cũng mất 32 bit thì điểm xác định kích thước của chúng là 8/16/16 bit trong java là gì?
dùng3222249

Vì vậy, chúng có thể được lưu trữ hiệu quả hơn trong mảng.
Robert Harvey

Câu trả lời:


11

TL; DR Điều duy nhất chắc chắn là booleanchiếm ít nhất một bit. Mọi thứ khác phụ thuộc vào việc thực hiện JVM.

Đặc tả ngôn ngữ Java không xác định kích thước, chỉ phạm vi giá trị (xem Thông số ngôn ngữ ). Vì vậy, nó không chỉ có booleankích thước không xác định ở cấp độ này. Và booleancó hai giá trị có thể: falsetrue.

Các Virtual Machine Đặc điểm kỹ thuật cho chúng ta biết booleanbiến được đối xử như intvới các giá trị 0 và 1. Chỉ mảng của booleancó hỗ trợ cụ thể. Vì vậy, ở cấp độ Máy ảo, một booleanbiến chiếm cùng một dung lượng như một int, nghĩa là một ô ngăn xếp: ít nhất 4 byte, thường là 4 byte trên Java 32 bit và 8 byte trên 64 bit.

Cuối cùng, có công cụ HotSpot biên dịch mã byte JVM thành mã máy cụ thể của CPU được tối ưu hóa và tôi cá rằng trong nhiều trường hợp, nó có thể suy ra phạm vi giá trị giới hạn của một int-masked booleantừ ngữ cảnh và sử dụng kích thước nhỏ hơn.


Như robert và bạn cũng gián tiếp nói rằng Nếu các kiểu dữ liệu nguyên thủy byte / char / ngắn cũng mất 32 bit thì câu hỏi của tôi là điểm xác định kích thước của chúng là 8/16/16 bit trong java là gì?
dùng3222249

Điểm xác định phạm vi giá trị giới hạn của chúng (hoặc "kích thước", nếu bạn thích) là ngữ nghĩa của chúng, ví dụ bao quanh từ 127 đến -128. Thường là không mong muốn, nhưng đôi khi hữu ích. Và sau đó là các mảng của các loại ngắn hơn, và chúng thực sự chiếm ít không gian hơn các mảng int. Và cuối cùng, tiềm năng của trình biên dịch JIT / công cụ HotSpot là tối ưu hóa không gian xuống dưới 4 byte.
Ralf Kleberhoff

8

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ó sizeoftoá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.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.