2012-01-19 40 views
10
  • Tôi đã tò mò về tất cả các vị trí mà JVM tìm kiếm để thực hiện chương trình? Tôi quan tâm nhiều hơn đến sự hiểu biết về trình tự nào và JVM tìm kiếm các tệp lớp nào, giống như nó nhìn vào các thư viện java, libs mở rộng, classpath bất kỳ thư mục nào như thư mục hiện tại từ nơi java được gọi? Tôi quan tâm nhiều hơn đến hành vi JVM và không phải là cách lớp tải lớp tải, mà tôi biết có cơ chế ủy nhiệm cha mẹ cho đến gốc.Cách JVM bắt đầu tìm kiếm các lớp học?

  • Nếu một lớp được thực thi từ thư mục mà lớp được biên dịch được lưu trữ trên hệ thống tệp và cũng trong tệp jar trong cùng một thư mục, JVM sẽ tải cả hoặc chỉ một và cái nào?

  • Giả sử bạn có một chuỗi không an toàn Vector và nếu chúng tôi so sánh hiệu suất với ArrayList, cái nào sẽ tốt hơn và tại sao?

+8

Điểm nào trong số các dấu đầu dòng này không thuộc về? –

+0

Viên đạn thứ 3 có lẽ nên được xem xét riêng. Đầu tiên 2 có liên quan và khớp với tiêu đề câu hỏi của bạn. Thứ ba thì không. – rfeak

+0

Tôi sẽ xử lý lần sau @rfeak –

Trả lời

7

Cách tìm lớp học. trả lời là ở đây:

http://docs.oracle.com/javase/1.5.0/docs/tooldocs/findingclasses.html

trả lời cho điểm 2: Trình tự tìm các lớp học như sau:

  1. lớp hoặc gói trong thư mục hiện hành.
  2. các lớp được tìm thấy từ biến môi trường CLASSPATH. [ghi đè 1]
  3. các lớp được tìm thấy từ tùy chọn dòng lệnh -classpath. [Ghi đè 1,2]
  4. lớp tìm thấy từ kho lưu trữ jar định qua -jar tùy chọn dòng lệnh [ghi đè 1,2,3]

Vì vậy, nếu bạn sử dụng tùy chọn -jar trong khi chạy, các lớp học đến từ jarfile.

Chỉ một lớp được tải mặc dù.

+0

Các câu trả lời dựa trên liên kết không được khuyến khích ở đây. – RanRag

+0

Cảm ơn @ Rajendran T, point2: nói rằng chúng tôi không chỉ định bất kỳ đường dẫn lớp nào, điều gì sẽ xảy ra trong trường hợp đó? sẽ jvm tải cả hai hoặc nếu chỉ có một trong số họ sau đó mà một trong những? –

+0

@Taran nếu bạn không đặt classpath trong môi trường (point2) hoặc trên dòng lệnh (điểm 3) thì classpath mặc định chỉ bao gồm thư mục làm việc hiện tại. – Dev

1
  1. Tôi tin Java sẽ tìm trong thư mục hiện tại, sau đó tại đường dẫn lớp, theo đối số VM "-cp". Bạn có thể đặt bất kỳ sự kết hợp nào của các thư mục của các lớp (ví dụ/project/bin/com/putable), các tệp lớp cụ thể (ví dụ /project/bin/com/putable/MyClass.class) và các tệp JAR (ví dụ/project/lib/MyJar.jar) trên đường dẫn lớp. Các vị trí được phân tách bằng dấu hai chấm (các hệ điều hành dựa trên Unix) hoặc dấu chấm phẩy (các hệ điều hành dựa trên Windows). Vì vậy, bất cứ điều gì trên classpath là trò chơi công bằng cho Java để xem xét khi có được định nghĩa lớp. Đối với trình tự, các lớp được nạp lazily. Vì vậy, chúng chỉ được tải khi ứng dụng của bạn yêu cầu chúng lần đầu tiên. Nếu ứng dụng của bạn không yêu cầu một lớp nhất định trong suốt thời gian chạy của nó, thì lớp đó sẽ KHÔNG BAO GIỜ được tải.

  2. Nếu bạn không đặt bất kỳ thứ gì trên đường dẫn lớp, tôi nghĩ Java sẽ tải từ tệp lớp chứ không phải tệp Jar. Nếu bạn chỉ định một hoặc cái khác trên classpath, thì đó là nơi mà Java sẽ tìm kiếm. Nếu bạn đặt cả hai trên classpath, hành vi tải lớp của Java là không xác định và nó có thể chọn một trong hai, tùy thuộc vào việc thực hiện JVM.

  3. Phụ thuộc vào những gì bạn muốn làm. Vectơ thực sự luôn là luồng an toàn, theo API Java, vì vậy nếu bạn không yêu cầu truy cập đồng thời, ArrayList sẽ nhanh hơn. Vectơ và ArrayLists đều được hỗ trợ bởi mảng, nhưng chúng tăng công suất ở các mức khác nhau (dung lượng của Vector tăng gấp đôi khi kết thúc đạt được và cần nhiều không gian hơn, nhưng ArrayList tăng 50%).Tùy thuộc vào mức độ thường xuyên bạn phải tăng trưởng hoặc thu hẹp, câu trả lời sẽ thay đổi. Kiểm tra liên kết này để biết thêm:

http://www.javaworld.com/javaworld/javaqa/2001-06/03-qa-0622-vector.html

6

Nếu không sử dụng bất kỳ classloader thêm:

  • Tìm kiếm trật tự cho một JVM:
    1. lớp Runtime (về cơ bản, rt.jar trong $JRE_HOME/lib `)
    2. Các lớp mở rộng (một số JAR trong số $JRE_HOME/lib/ext`)
    3. Đường dẫn, theo thứ tự. Có bốn khả năng để chỉ định đường dẫn lớp:
      1. Nếu được chỉ định -jar thì JAR nằm trong đường dẫn lớp. Dù classpath được khai báo là classpath trong META-INF/MANIFEST.MF cũng được xem xét.
      2. Khác, nếu -cp được chỉ định, đó là đường dẫn lớp.
      3. Khác, nếu $CLASSPATH được đặt, đó là đường dẫn lớp.
      4. Khác, thư mục hiện tại mà từ đó java đã được khởi chạy là đường dẫn lớp.
      Vì vậy, nếu tôi chỉ định -cp src/A.jar:src/B.jar, sau đó A.jar sẽ được tìm kiếm đầu tiên, sau đó B.jar
  • Các JVM tải chỉ lớp mà được tìm thấy đầu tiên, theo thứ tự mà các thư mục/lọ được khai báo trong classpath. Điều này quan trọng nếu bạn sử dụng -cp hoặc $CLASSPATH.
  • Trong kịch bản chủ đề duy nhất và với JVM gần đây, VectorArrayList nên có hiệu suất tương tự (ArrayList nên thực hiện tốt hơn một chút vì nó không phải là synchronized, nhưng khóa hiện nhanh chóng khi không có tranh chấp, vì vậy sự khác biệt nên nhỏ). Dù sao, Vector đã lỗi thời: không sử dụng nó trong mã mới.
1

Tôi quan tâm nhiều hơn trong hành vi JVM và không bao lớp loader tải lớp

Xin lỗi, nhưng điều này là vô nghĩa. Vì câu trả lời là JVM tạo một trình nạp lớp và cho phép trình nạp lớp này nạp các lớp. Vì vậy, để hiểu được "hành vi JVM", bạn cần hiểu hành vi của trình nạp lớp.

Nhưng có thể câu hỏi của bạn là: JVM tạo bộ nạp lớp hệ thống như thế nào?

+0

Đây là nhận xét nhiều hơn là câu trả lời. – cHao

0

Đầu tiên, theo mặc định, hệ thống thời gian chạy Java sử dụng thư mục làm việc hiện tại làm điểm khởi đầu của nó. Do đó, nếu gói của bạn nằm trong thư mục con của thư mục hiện tại, nó sẽ được tìm thấy. Thứ hai, bạn có thể chỉ định đường dẫn thư mục hoặc đường dẫn bằng cách đặt biến môi trường CLASSPATH. Thứ ba, bạn có thể sử dụng tùy chọn -classpath với java và javac để chỉ định đường dẫn đến các lớp của bạn.
Ví dụ: hãy xem xét đặc điểm kỹ thuật của gói sau:

gói MyPack;

Để chương trình tìm MyPack, một trong ba điều phải đúng. Hoặc là chương trình có thể được thực hiện từ thư mục ngay trên MyPack hoặc CLASSPATH phải là được đặt để bao gồm đường dẫn đến MyPack hoặc tùy chọn -classpath phải chỉ định đường dẫn đến MyPack khi chương trình được chạy qua java. Khi hai tùy chọn thứ hai được sử dụng, đường dẫn lớp không được bao gồm MyPack. Nó chỉ cần chỉ định đường dẫn đến MyPack. Ví dụ, trong một môi trường Windows, nếu con đường để MyPack là

C: \ MyPrograms \ Java \ MyPack

thì đường dẫn lớp để MyPack là

C: \ MyPrograms \ Java

Cách dễ nhất để thử các ví dụ được hiển thị là tạo các gói thư mục bên dưới thư mục phát triển hiện tại của bạn, đặt các tệp .class vào các thư mục thích hợp và sau đó thực hiện các chương trình từ thư mục phát triển. Đây là phương pháp được sử dụng trong ví dụ sau.

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