2011-12-21 3 views
17

Cách tôi nhìn thấy nó (sửa tôi nếu tôi sai) một lớp được lưu trữ, do đó cần tìm kiếm đường dẫn lớp là cần thiết lần đầu tiên lớp được tham chiếu. Nó sẽ chỉ xảy ra thường xuyên như trình khởi tạo tĩnh được gọi, chỉ là một lần trong suốt vòng đời của chương trình. (hoặc cụ thể hơn, Trình tải lớp)Là một đường dẫn lớp lớn của nhiều tệp jar (có lẽ thậm chí không được sử dụng) không hiệu quả

Nhưng trong trường hợp có một chương trình dài, dài bao gồm nhiều thư viện có thể hoặc không được sử dụng.

Các tệp Jar có được tải vào bộ nhớ, gây ra việc sử dụng không cần thiết do thực tế là hầu hết các lớp không bao giờ được sử dụng? Nó sẽ ở lại trong bộ nhớ?

Tham chiếu thư mục có phải là tùy chọn tốt hơn không? Hoặc là tệp Jar đã được giải nén vào một vị trí tạm thời để bắt đầu?

Sử dụng phương pháp thư mục có nhanh hơn phương pháp tệp Jar không?

Có hợp lý để trích xuất tất cả các tệp Jar vào một thư mục duy nhất, để giảm số lượng vị trí trong đường dẫn lớp không? Khi nào thì đây là một ý tưởng hay?

Trả lời

7

Thư mục tệp trung tâm của tệp jar (được đặt ở cuối zips) sẽ được phân tích cú pháp và được nạp vào bộ nhớ. Thư mục bằng phẳng nên tất cả thư mục cần được tải. Một phần quan trọng của sự chậm trễ khi bắt đầu một quá trình Java đơn giản là việc mở rt.jar rất lớn. Vì vậy, có đó là bắt đầu lên thời gian và chi phí bộ nhớ ngay tại đó.

Tra cứu từng lớp phải là thời gian không đổi. Tuy nhiên, có một số thuật toán O (n) ở đó. Vì vậy, đối với một ứng dụng nói chung là O (n^2) cho việc nạp lớp (mặc dù hằng số là khá nhỏ và có thể bị chi phối bởi các phép toán thời gian tuyến tính).

Thực hiện truy cập tệp trên nhiều tệp sẽ không hiệu quả.JDK đã sử dụng một zip cho các lớp hệ thống trước khi lọ.

(Lớp tải có thể xảy ra một số thời gian trước khi khởi động tĩnh khi initialiser tĩnh sẽ được chạy nếu có -. Thấy ba đối số Class.forName)

+0

Thư mục trung tâm không phân tích cú pháp vừa được ánh xạ (mmap) vào bộ nhớ và được giải quyết khi cần thiết (Tôi không nhớ lại mã hoàn toàn tốt nhưng cảm thấy gần như tích cực) – bestsss

+0

** Thực hiện truy cập tệp trên nhiều tệp sẽ không hiệu quả. JDK đã sử dụng một zip cho các lớp hệ thống trước khi jars. ** Đây là một điểm thú vị. Cách tôi nhìn thấy nó, sử dụng một jar (hoặc zip) tập tin là một thương mại-off. Sử dụng bộ nhớ bổ sung có nghĩa là tải lớp nhanh hơn. Cảm ơn vì thông tin của bạn. –

+0

@bestsss Khi cố gắng tìm một lớp học, mỗi bình sẽ cần được mở trong thời hạn. Bạn sẽ rất may mắn xảy ra để có tất cả các lớp học của bạn trong lọ sớm. Bạn cũng có thể gặp sự cố khi tìm kiếm tài nguyên chẳng hạn. –

11

Đây không phải là vấn đề, bạn không nên lo lắng về điều đó. Trình tải lớp đủ thông minh để tải các lớp mà nó cần và thường tải các lớp theo yêu cầu (nghĩa là nó không thường tải lên một nhóm mã mà sẽ không được sử dụng). Điều này không liên quan gì đến việc ứng dụng của bạn chạy được bao lâu hoặc dài.

Trong trường hợp một số lượng lớn các JAR, tôi muốn được quan tâm nhiều hơn về JAR Hell. Theo như câu hỏi nhanh hơn, tôi cho rằng có thể có một số khác biệt giữa các cách tiếp cận khác nhau, nhưng nếu bạn có thể dễ dàng tự mình kiểm tra điều này bằng cách thử qua thử nghiệm. Tình huống có thể là ứng dụng cụ thể, vì mã mà mỗi ứng dụng tải là khác nhau.

Tôi nghĩ câu trả lời là smooth reggae's là một số chi tiết bổ sung về chủ đề tải lớp.

+2

@GeorgeBailey Cũng từ sự hiểu biết của tôi nhất định JVM thực hiện -Khách hàng và JVM -server parms. The -client parm yêu cầu JVM chỉ nạp các lớp khi cần thiết (và thậm chí là các lớp thu gom rác không được sử dụng trong một thời gian) để tăng tốc độ khởi động ban đầu của ứng dụng của bạn. Tùy chọn -server làm cho JVM tải chậm hơn vì nó phân tích các lớp được nạp và tìm xem những lớp nào cần giữ trong bộ nhớ lâu hơn dựa trên cách sử dụng. Nếu bạn có một ứng dụng chạy dài, tùy chọn máy chủ thường đáng giá. Một lần nữa, kiểm tra JVM của bạn để xem nếu có những parms. –

+1

@normalocity, Chúng tôi sẽ cẩn thận. ** "hai phiên bản khác nhau của thư viện" ** sẽ tránh được như bệnh dịch hạch. ** "yêu cầu các phiên bản khác nhau" ** có thể sẽ không bao giờ xảy ra, nhưng nếu có, chúng tôi sẽ xử lý nó với một quá trình riêng biệt hoặc trình nạp lớp. ** "một số (có thể rất nhiều) lồng nhau, bộ nạp lớp hợp tác" ** sẽ bị ngăn chặn bởi thiết kế. Tuy nhiên, câu hỏi chỉ được trả lời một phần. Tất cả các tệp jar được nạp vào bộ nhớ? Bằng cách này, tôi có nghĩa là các tập tin lớp học, không phải lớp học thực tế. –

+0

@Chris, Cảm ơn bạn vì thông tin hữu ích đó. –

3

How classes are foundthe chapter on loading, linking and initializing trong đặc điểm JVM là tài liệu tham khảo hữu ích.

Từ kinh nghiệm cá nhân, tôi có thể chứng thực rằng đường dẫn lớp học của bạn dài hơn cho javac thì càng mất nhiều thời gian để biên soạn; điều này đặc biệt là một vấn đề khi classpath của bạn có các tính năng JAR không cần thiết cho việc biên dịch. Đối với một thử nghiệm đơn giản, hãy thử biên dịch HelloWorld.java kinh điển mà không cần -cp, với một vài tệp JAR được thêm vào -cp và sau đó với một số tệp JAR được thêm vào -cp; thời gian thực hiện để biên dịch tăng lên khi số lượng JAR trong danh sách -cp tăng lên.

+0

Điểm thú vị về biên dịch. Tuy nhiên, đối với trường hợp cụ thể của tôi, đường dẫn lớp dài chỉ dành cho thời gian chạy. Không biên dịch thời gian, vì điều đó xảy ra ở những phần nhỏ. –