2009-03-01 44 views
6

Tôi đang cố gắng thực hiện một số điểm chuẩn của các JVM chạy trên các nền tảng phần cứng và hệ điều hành khác nhau. Tôi đã tạo một thuật toán để thực hiện các phần của JVM mà tôi quan tâm và có ý định chạy thuật toán này nhiều lần để tìm mức trung bình khá.Đang tải xuống lớp java của lớp học

Khi tôi chạy benchmark, tôi thấy rằng thời gian đầu tiên là dài hơn đáng kể hơn so với chạy tiếp theo:

132ms 
86ms 
77ms 
89ms 
72ms 

nghi ngờ của tôi là lớp được nạp một cách lười biếng, đặt một chi phí lớn về thời gian đầu tiên. Trong khi điều này thực sự là một tính năng mà tôi giả định là duy nhất cho mỗi JVM, nó không phải là một trong tôi quan tâm đến thời điểm này.

Có tùy chọn dòng lệnh hoặc thuộc tính tiêu chuẩn để tải các lớp học háo hức không? hoặc có ai có lý thuyết nào khác không?

Trả lời

5

Điều đơn giản nhất cần làm là bỏ qua lần chạy đầu tiên. Lưu ý: nếu bạn chạy cùng một mã 10.000 lần, nó sẽ biên dịch mã thêm và bạn nhận được kết quả tốt hơn, vì vậy bạn có thể muốn bỏ qua kết quả 10K đầu tiên cho một số điểm chuẩn vi mô.

Một số JVM hỗ trợ tải mong muốn nhưng tôi không nghĩ JVM của Sun làm.

+0

Tôi không thể nhận được nó sẽ biên dịch mã thêm. hãy giải thích về điều này, và tại sao chỉ sau 10000 lần chạy, người ta có thể nhận được kết quả thích hợp cho vi điểm chuẩn (trung bình) –

+0

"ngưỡng biên dịch" mặc định là 10000. xem '-XX: CompileThreshold = 10000' Điều này có nghĩa là mã không được tối ưu hóa đầy đủ cho đến khi nó chạy 10.000 và bạn có thể muốn bỏ qua các lần chạy này để có được kết quả tốt nhất. Trong mọi trường hợp, tôi đề nghị chạy thử nghiệm trong ít nhất 2-10 giây. –

+0

trong trường hợp đó nếu tôi cung cấp -XX: CompileThreshold = 10, thì chúng tôi rất tốt để kiểm tra nó cho một vòng 10000 (yup, tôi biết nó sẽ chỉ chạy cho một số millisecs) –

2

Sử dụng java -XX:+TraceClassLoading để theo dõi tải lớp.

Sử dụng java -XX:+PrintCompilation để theo dõi khi phương pháp được JIT.

0

Không có tùy chọn dòng lệnh chuẩn vì đó không phải là một phần của thông số JVM. Tải lớp lười biếng là (được cho phép rõ ràng là một phần) của thông số JVM. Bạn có thể sử dụng Class.forName() trước khi chạy để tải các lớp bạn biết, nhưng nó không tự động chuyển tiếp.

Tính năng biên dịch HotSpot cũng sẽ có hiệu lực trong vài lần chạy đầu tiên - một phương pháp được diễn giải một vài lần trước khi được biên soạn và quá trình biên dịch diễn ra một thời gian.

4

Quy tắc số 1 cho điểm chuẩn Java: 15000 lần đầu tiên (hoặc lâu hơn) phương pháp chạy không thú vị.

chủ đề này có chứa một số lời khuyên rắn: How do I write a correct micro-benchmark in Java?

+0

Nói cách khác: Java là nhanh chóng nếu bạn bỏ qua khi nó là chậm :-) – marcus

4

Nếu bạn muốn để buộc các lớp được nạp làm một cái gì đó như thế này:

public class Main 
{ 
    static 
    { 
     loadClasses(); 
    } 

    public static void main(final String[] argv) 
    { 
     // whatever 
    } 

    private static void loadClasses() 
    { 
     final String[] classesToLoad; 

     // even better, read them from a file and pass the filename to this method 
     classesToLoad = new String[] 
     { 
      "foo.bar.X", 
      "foo.bar.Y", 
     } 

     for(final String className : classesToLoad) 
     { 
      try 
      { 
       // load the class 
       Class.forName(className); 
      } 
      catch(final ClassNotFoundException ex) 
      { 
       // do something that makes sense here 
       ex.printStackTrace(); 
      } 
     } 
    } 
} 
+0

nếu một trong những muốn tải các lớp học, khi và khi lớp chính tải, ông có thể nhập khẩu, nhu cầu của lớp là gì.forName –

+0

@Naroji nhập khẩu là một trình biên dịch chỉ điều, nó không có gì tại thời gian chạy. – TofuBeer

+0

Vui lòng xác thực ... lớp có thể được nạp vào khu vực phương thức jvm bởi ClassLoader, Class.forName hoặc Nhà điều hành mới, DI, Nhà máy (nội bộ tất cả chúng chỉ sử dụng classLoader) ... mới, DI, Nhà máy cũng tạo đối tượng –

1

Một khi bạn đã các lớp được nạp, để tránh chạy phiên dịch sử dụng -Xcomp (trên triển khai Sun) để chỉ chạy mã được biên dịch. Nó có thể rất chậm chạy các ứng dụng bình thường theo cách này vì tất cả các mã phải được biên dịch chứ không phải chỉ là một vài phần.

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