2012-04-18 90 views
49

Tôi hiện đang cố gắng tìm hiểu kỹ hơn về đặc tả của Máy ảo Java. Tôi đã đọc Inside the JVM book online và có một trừu tượng khó hiểu tôi dường như không thể hiểu được: Constant Pool. đây là trích đoạn từ sách:Mục đích của Java Constant Pool là gì?

Đối với mỗi loại tải, máy ảo Java phải lưu trữ một nhóm không đổi. Một nhóm không đổi là một tập hợp các hằng số được sắp xếp được sử dụng bởi kiểu, bao gồm các hằng số (chuỗi, số nguyên và các hằng số dấu chấm động) và các tham chiếu tượng trưng cho các kiểu, các trường và các phương thức. Các mục trong nhóm hằng số được tham chiếu theo chỉ mục, giống như các phần tử của một mảng. Vì nó chứa các tham chiếu tượng trưng cho tất cả các loại, trường và phương thức được sử dụng theo loại, nhóm hằng số đóng vai trò trung tâm trong liên kết động của các chương trình Java

Tôi có một số câu hỏi về phía trên và CP nói chung:

  1. CP có nằm trong .class tệp cho từng loại không?
  2. Tác giả có ý nghĩa gì bởi "tham chiếu tượng trưng"?
  3. Mục đích của Hồ bơi không đổi là gì, bằng tiếng Anh đơn giản?

Trả lời

51

Tôi nghĩ rằng sự hiểu biết cách khung được xây dựng bằng cách sử dụng biểu đồ sẽ giúp ích.

enter image description here

Khung là nơi mà các toán hạng (hướng dẫn vận hành) cư trú và đó là nơi mà các liên kết động xảy ra. Đó là một cách viết tắt, vì vậy để nói chuyện, sử dụng các hồ bơi liên tục để theo dõi các lớp học và các thành viên của nó.

Mỗi khung chứa tham chiếu đến hồ bơi hằng số thời gian chạy. Các tham chiếu trỏ đến nhóm hằng số cho lớp của phương thức đang được thực hiện cho khung đó. Tham chiếu này giúp hỗ trợ liên kết động.

Mã C/C++ thường được biên dịch thành tệp đối tượng, sau đó nhiều tệp đối tượng được liên kết với nhau để tạo thành một tạo phẩm có thể sử dụng như tệp thi hành hoặc dll. Trong phần liên kết các tham chiếu tượng trưng trong mỗi tệp đối tượng được thay thế bằng một địa chỉ bộ nhớ thực tế liên quan đến tệp thực thi cuối cùng. Trong Java, giai đoạn liên kết này được thực hiện tự động khi chạy.

Khi tệp Java được biên dịch, tất cả các tham chiếu đến các biến và phương thức được lưu trữ trong nhóm hằng số của lớp như một tham chiếu tượng trưng. Một tham chiếu tượng trưng là một tham chiếu logic không phải là một tham chiếu thực sự trỏ đến một vị trí bộ nhớ vật lý.

Đây là liên kết đến James Blooms JVM Internals để biết thêm chi tiết.

+0

"Khi một lớp Java được biên dịch ..."? Tệp .class không phải là mã Java đã biên dịch chưa? –

+1

Có, tệp .java sẽ trở thành tệp .class khi được biên dịch. –

+0

liên kết bị hỏng –

6

Mục đích của Hồ bơi không đổi, bằng tiếng Anh đơn giản là gì?

Các CP là một khu vực bộ nhớ giá trị không đổi rất độc đáo được lưu trữ để giảm sự dư thừa:

System.err.println("Hello"); 
System.out.println("Hello"); 

Trong CP chỉ có sản phẩm thay thế một đối tượng String "Hello" và trình biên dịch trong cả hai dòng đến cùng một tham chiếu. Tệp .class của bạn chỉ chứa một chuỗi Hello. (Tương tự cho các loại khác).

CP có nằm trong tệp .Class cho từng loại không?

Vâng, Nhìn đây: http://en.wikipedia.org/wiki/Java_class_file

+0

Bạn có mở rộng thêm một chút về các liên kết tượng trưng có lẽ? Tôi nghĩ đây là phần quan trọng nhất của CP – Bober02

63

hồ bơi liên tục là một phần của .class tập tin (và đại diện trong bộ nhớ của nó) có chứa các hằng số cần thiết để chạy mã của lớp đó.

Các hằng số này bao gồm các chữ được chỉ định bởi trình lập trình và các tham chiếu tượng trưng được tạo bởi trình biên dịch. Các tham chiếu tượng trưng về cơ bản là tên của các lớp, các phương thức và các trường được tham chiếu từ mã. Các tham chiếu này được JVM sử dụng để liên kết mã của bạn với các lớp khác mà nó phụ thuộc vào.

Ví dụ, đoạn mã sau

System.out.println("Hello, world!"); 

tạo ra bytecode sau (javap đầu ra)

0: getstatic  #2; //Field java/lang/System.out:Ljava/io/PrintStream;    
3: ldc  #3; //String Hello, world!             
5: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V 

#n đây là tài liệu tham khảo đến hồ bơi liên tục. #2 là tham chiếu tượng trưng cho trường System.out, #3 là một chuỗi Hello, world!#4 là tham chiếu tượng trưng cho phương thức PrintStream.println(String).Như bạn có thể thấy, tham chiếu tượng trưng không chỉ là tên - ví dụ, tham chiếu tượng trưng cho phương thức cũng chứa thông tin về các tham số của nó (Ljava/lang/String;) và kiểu trả về (V có nghĩa là void).

Bạn có thể kiểm tra hồ bơi không đổi của một lớp bằng cách chạy javap -verbose cho lớp đó.

+0

@ axtavt- wow! lời giải thích tốt đẹp. trông giống như một lỗi đánh máy nhỏ gần "# 3 là một tham chiếu tượng trưng cho PrintStream .." không nên là # 4 –

+0

@mashit: Có, đã sửa. – axtavt

+0

Nhưng "L" có nghĩa là gì trong "Ljava/lang/String;" ? – JackWM

1

Hãy cho ví dụ đầu tiên để hiểu những gì Chuỗi hồ bơi liên tục có nghĩa là

public class StringConstantPool { 
     public static void main(String[] args) { 
      String s = "prasad"; 
      String s2 = "prasad"; 

      System.out.println(s.equals(s2)); 
      System.out.println(s == s2); 
     } 
    } 

sản lượng sẽ được

true 

true 

những gì xảy ra ở đây từng bước

1- Các lớp được nạp khi JVM được gọi.

2- JVM sẽ tìm tất cả các chuỗi ký tự trong chương trình.

3 Thứ nhất, nó tìm biến s trong đó đề cập đến nghĩa đen “Prasad” và nó sẽ được tạo ra trong bộ nhớ

4 Một tài liệu tham khảo cho các literal “Prasad” sẽ được đặt trong bộ nhớ nhóm hằng số chuỗi.

5 Sau đó nó tìm thấy một biến s2 mà là đề cập đến cùng một chuỗi chữ “Prasad”.

Bây giờ JVM đã tìm thấy một chuỗi chữ “Prasad”, cả biến s và s2 wil tham khảo cùng một đối tượng ví dụ: “Prasad”.

enter image description here

Tôi hy vọng điều này rất hữu ích

đọc thêm http://www.journaldev.com/797/what-is-java-string-pool

+2

Không có thứ gì như 'Chuỗi hằng số chuỗi'. Có 'nhóm liên tục' tồn tại trong mỗi tệp lớp và có 'chuỗi nhóm' của chuỗi nội bộ tồn tại cho JVM. – Keenle

+0

yea, ở đây tôi có nghĩa là chuỗi hồ bơi, Cảm ơn bạn đã bình luận –

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