2015-09-11 25 views
5

Tôi tò mò về cách các trường staticfinal được JVM xử lý. Tôi đã thấy một câu hỏi tương tự here nhưng đó không phải là những gì tôi đang tìm kiếm. Chúng ta hãy xem xét ví dụ như:trường cuối cùng tĩnh và cuối cùng không tĩnh và tối ưu hóa JVM

public class TestClassX { 
    public final int CODE_A = 132; 
    public final int CODE_B = 948; 
    public final int CODE_C = 288; 
    // some other code 
} 

public class TestClassY { 
    public static final int CODE_A = 132; 
    public static final int CODE_B = 948; 
    public static final int CODE_C = 288; 
    // some other code 
} 

Trong TestClassX lĩnh vực, vì họ là final và không thể được sửa đổi, có giá trị như nhau trong tất cả các trường của lớp TestClassX. Tất nhiên tôi không thể viết TestClassX.CODE_A nhưng tôi có thể nói, rằng những giá trị này thực sự phổ biến cho tất cả các trường hợp - tôi chắc chắn rằng mỗi trường hợp có một trường CODE_A với giá trị 132.

Trong TestClassY Tôi có thể sử dụng cú pháp TestClassY.CODE_A, nhưng ngay từ cái nhìn đầu tiên, nhà phát triển thấy "Ồ, những giá trị này phổ biến cho mọi trường hợp".

câu hỏi chính của tôi: Tôi đoán rằng JVM, trong trường hợp TestClassX, không sử dụng bất kỳ bộ nhớ bổ sung cho final lĩnh vực mỗi lần một trường hợp mới được tạo ra. Phải không? JVM có thực hiện bất kỳ tối ưu hóa nào trong trường hợp này và loại tối ưu hóa nào không?

Câu hỏi thêm 1) Tôi cũng chắc chắn rằng tôi đang thiếu điều gì đó rất quan trọng ở đây là nguyên nhân gây ra những nghi ngờ của tôi. Cái gì thế?

Câu hỏi bổ sung 2) Btw. Làm thế nào tôi có thể xem xét mã nguồn Java của tôi trông như thế nào sau khi tối ưu hóa JVM (vì vậy tôi có thể sử dụng trong tương lai;))? Có bất kỳ IDE hỗ trợ chức năng như vậy không? IntelliJ chẳng hạn? Tôi muốn chỉ đơn giản là để xem cách JVM xử lý TestClassXTestClassY của tôi.

+0

liên quan - javac luôn inlines biến dụ liên tục, có thể là một lỗi :) - https://groups.google.com/forum/#!topic/java-lang-fans/AyS3UqX4lj4 – ZhongYu

+0

2) tối ưu hóa của JVM aren không được thực hiện theo cách mà chính nó được thể hiện dưới dạng nguồn Java. Trình biên dịch tối ưu hóa một biểu diễn bên trong của mã * làm *.trình tối ưu hóa nguồn-> thường chỉ tồn tại cho các ngôn ngữ phải được biên dịch mỗi khi chúng được sử dụng (ví dụ: javascript). Mục tiêu thực tế của bạn ở đây sẽ được đề cập đến bằng cách xem mã byte Java hoặc asm do việc biên dịch JIT cho một CPU cụ thể. (Hoặc trước khi biên dịch truyền thống cho việc triển khai Java như gcj'.) –

Trả lời

6
  • Trường không tĩnh luôn có trong các phiên bản. Họ không lưu bộ nhớ.
  • Nói chung JVM không tối ưu hóa các trường không tĩnh. Ngay cả khi họ là cuối cùng họ vẫn có thể được thiết lập để giá trị khác nhau bằng cách sử dụng phản ánh hoặc trong deserialization.
  • Có một tùy chọn VM thử nghiệm -XX:+TrustFinalNonStaticFields (tắt theo mặc định) cho phép JVM tối ưu hóa quyền truy cập vào các trường như vậy, tức là xử lý chúng dưới dạng hằng số và loại bỏ tải trường.
  • Có tùy chọn -XX:+PrintAssembly VM để kết xuất mã được biên dịch JIT.
+0

Cảm ơn bạn đã đề cập đến phản ánh và deserialization . Và đối với tùy chọn TrustFinalNonStaticFields - tôi không biết! ... ^ –

1

Đối với phần đầu tiên của câu hỏi, có thể this answer có thể giúp bạn.

Đối với phần thứ hai, bạn có thể xem hội đồng được tạo (như được nêu trong this answer) bằng cách thêm -XX:+PrintOptoAssembly cờ khi bạn chạy/biên dịch mã của bạn.

Tôi cũng nên thêm mã lắp ráp được cung cấp cho bạn không phải là mã opcode thực được tạo bởi jvm, nhưng mã cần thiết để chạy dưới cấu trúc thực tế của bạn.

Hy vọng điều này sẽ hữu ích!

+0

Xin lỗi vì đã không đăng nhận xét đó, nhưng tôi không có đủ danh tiếng để làm như vậy ... –

Các vấn đề liên quan