2011-01-14 26 views
31

Để tăng tốc thời gian khởi động của JVM, các nhà phát triển Sun quyết định nên biên dịch trước các lớp runtime chuẩn cho một nền tảng trong khi cài đặt JVM. Bạn có thể tìm thấy các lớp biên dịch sẵn này, ví dụ: tại địa chỉ:Tăng tốc độ khởi động ứng dụng bằng cách thêm các lớp ứng dụng riêng vào classes.jsa

$ JAVA_HOME \ jre \ bin \ client \ classes.jsa

Công ty của tôi hiện đang phát triển một ứng dụng độc lập Java mà mang JRE riêng của mình, vì vậy nó sẽ là một lựa chọn tuyệt vời để tăng tốc độ ứng dụng của chúng tôi thời gian bắt đầu bằng cách thêm các lớp ứng dụng riêng của chúng tôi vào tệp jsa này.

Tôi không tin rằng tệp JSA đã được tạo bởi ma thuật, vì vậy: Làm thế nào nó được tạo ra? Và làm thế nào tôi có thể lừa JVM kết hợp các lớp học của riêng tôi?

EDIT: Tôi đã phát hiện ra những điều sau đây:

Các classes.jsa được tạo ra bởi lệnh

java -Xshare:dump 

Danh sách các lớp học để kết hợp trong bãi có thể được tìm thấy trong $JAVA_HOME/jre/lib/classlist.

Tôi thậm chí còn quản lý thêm các lớp của riêng mình ở đây (và thêm chúng vào rt.jar để tìm java) và tạo checksum của riêng tôi bên dưới tệp danh sách lớp.

Vấn đề cuối cùng là: Chỉ có các lớp trong gói java, com.sun và org.w3c dường như được nhận diện, nếu tôi để cùng các lớp trong gói ban đầu, chúng sẽ không được tải. Tôi đã tìm kiếm toàn bộ nguồn OpenJDK cho con trỏ về điều này, nhưng dường như nó có liên quan đến các miền bảo vệ. Nếu ai đó đủ quan tâm đến chủ đề này và đủ hiểu biết, hãy thêm một số gợi ý cho tôi để đầu tư thêm.

+0

Bạn có thể chia sẻ cách bạn tính toán lại kiểm tra không? – coppit

+2

Tôi tìm thấy câu trả lời của mình trong một trang trình bày cho Java nhúng - có một tiện ích được gọi là AddJsum trong cây nguồn openjdk. http://www.oracle.com/technetwork/jp/ondemand/java/20110519-java-a-1-greg-400531-ja.pdf – coppit

+0

Cảm ơn, tôi có thể thử điều này khi tôi nhận được thời gian. – Daniel

Trả lời

8

Kể từ Java 8u40 (và Java 8u51 nhúng), Java hiện hỗ trợ Chia sẻ dữ liệu lớp ứng dụng (AppCDS) (tức là các lớp của riêng bạn trong kho lưu trữ được chia sẻ). Trên java nhúng của chúng tôi, chúng tôi đã tìm thấy một cải tiến khởi động> 40%! Khá tuyệt vời cho hầu như không có công việc trên một phần của chúng tôi ...

https://blogs.oracle.com/thejavatutorials/entry/jdk_8u40_released

+0

Tuyệt vời! Tôi sẽ bắt đầu đọc nó ngay lập tức :)! – Daniel

+0

Chính xác những gì tôi muốn. Đáng buồn thay, nó chỉ có sẵn như là một tính năng thương mại. Nhưng ít nhất nó có vẻ hoạt động. – Daniel

+0

Đáng buồn thay, Oracle chỉ giữ tính năng AppCDS trong cho Embedded cho phiên bản 8u51 ... chúng tôi đã cố gắng để có được một câu trả lời về nếu/khi nó sẽ trở lại từ Oracle ... nhưng không có may mắn. Chúng tôi có một câu trả lời nửa về "Wow - nhóm sản phẩm của chúng tôi rất muốn biết trải nghiệm của bạn với nó", nhưng sau đó chúng tôi không bao giờ có phản hồi về cách liên lạc với họ. – Ben

8

Ý tưởng thú vị. Như tôi đã đọc nó, nó được sử dụng để chia sẻ dữ liệu trên các máy ảo và để tăng tốc độ tải lớp, không biên dịch. Tôi không chắc chắn bạn sẽ nhận được bao nhiêu, nhưng nó có thể là một thử nếu bạn có một lag lớn lúc khởi động đã (mặc dù VM đã cố gắng để giảm thiểu điều đó).

Để tự mình thử, có vẻ tệp này thường được tạo khi máy ảo Sun được cài đặt, nhưng bạn cũng có thể kiểm soát nó. Một số chi tiết có trong tài liệu Sun Java 5 Class Data Sharing cũ hơn (mà bạn có thể đã thấy?). Một số tài liệu Sun Java 6 cũng mention it a few times, nhưng không thêm nhiều vào tài liệu. Có vẻ như ban đầu nó là IBM VM feature. Và, để tiếp tục đổ kết nối, nó được giải thích một chút in this article.

Tôi không biết nhiều về nó, vì vậy tôi không biết cách bạn có thể kiểm soát nó. Bạn có thể tạo lại nó, nhưng tôi không nghĩ rằng nó dành cho bạn để đưa công cụ tùy chỉnh vào. Ngoài ra, ngay cả khi bạn có thể "lừa" nó, điều đó có lẽ sẽ vi phạm một giấy phép Sun/Oracle của một số loại (bạn không thể gây rối với rt.jar và phân phối lại, ví dụ). Và, tất cả những gì đã nói, tôi nghi ngờ bạn sẽ thấy sự cải thiện nghiêm trọng trong thời gian khởi động trừ khi bạn có hàng ngàn hoặc hàng chục nghìn lớp trong ứng dụng của mình?

(Và đây không thực sự là câu trả lời, tôi biết, nhưng nó quá lớn để phù hợp với nhận xét, và tôi thấy câu hỏi thú vị nên tôi đã nghiên cứu một chút và đặt liên kết ở đây trong trường hợp ai đó tìm thấy cùng một thông tin hữu ích.)

+0

+1 Cảm ơn rất nhiều vì nỗ lực tuyệt vời của bạn. Tôi sẽ đọc qua các liên kết của bạn và hy vọng trở lại với một giải pháp làm việc. Ngoài ra tôi không biết rằng tôi đã không được phép fiddle với rt.jar và phân phối lại nó, nhưng tôi sẽ không quan tâm cho điều này anyway, bởi vì các ứng dụng duy nhất sử dụng nó sẽ là của tôi. – Daniel

+0

@Charlie, liên kết thứ hai của bạn bị tắt ....... – Pacerier

11

Bạn đã gần đến đó, bạn chỉ cần một vài bước để làm cho nó hoạt động. Để thêm các lớp học của riêng bạn cho khách hàng.js bạn cần các bước sau:

  1. Tên trình độ lớp học của bạn (bạn có nó)

  2. Các classpath của các lớp này (bạn có nó)

  3. biết làm thế nào để tính toán lại checksum (bạn có nó)

  4. Dump tệp mới, cung cấp đường dẫn lớp của các lớp bạn hiện đang biên dịch trước với các lớp Java.

  5. Chạy chương trình, cung cấp classpath tương tự mà bạn sử dụng để đổ classes.jsa mới

Để cung cấp classpath đâu các lớp bạn đang thêm vào classlist, sử dụng lệnh -Xbootclasspath/a. Nó sẽ nối thêm các thư mục/các JAR khi JVM đang tìm kiếm các vị trí có các lớp khởi động. Không gian mặc định cho classes.jsa là khá nhỏ, nếu bạn cần cải thiện nó, bạn có thể sử dụng các lệnh -XX:SharedReadWriteSize-XX:SharedReadOnlySize. Lệnh kết xuất của bạn trông giống như sau:

java -Xshare:dump -Xbootclasspath/a:C:/myfiles/directoryA/;C:/myfiles/directoryB/;C:/myJars/myJar.jar; 

Bước cuối cùng chỉ chạy ứng dụng java bình thường, nhớ lại bật chế độ chia sẻ. Bạn cũng cần thêm đoạn mã Xbootclasspath khi bạn thêm vào bãi chứa. Nó sẽ trông giống như thế này:

java myapp.java -Xshare:on -Xbootclasspath/a:C:/myfiles/directoryA/;C:/myfiles/directoryB/;C:/myJars/myJar.jar; 

Bây giờ mọi lớp bạn đưa vào danh sách lớp đang được chia sẻ với các trường hợp khác đang chạy trong cùng một JVM.

+0

Âm thanh tuyệt vời. Tôi chắc chắn sẽ kiểm tra điều này! – Daniel

+0

Tôi đang thử điều này và không thành công. Tôi đã tạo một tệp classfiles mới và thêm checksum và chỉ định -Xbootclasspath/a:/path/to/jars/*. Tệp classes.jsa kết quả có cùng kích thước với tệp gốc. Có thể là như Daniel đề nghị, các -Xshare: dump sẽ chỉ đổ lớp từ các gói cụ thể? Lý do tôi quan tâm đến điều này là chúng tôi sử dụng rất nhiều libs của bên thứ ba đang làm tăng mức sử dụng bộ nhớ RSS của chúng tôi.Nó sẽ là tốt đẹp để có được những chia sẻ giữa các JVM như thư viện chuẩn là. (Và có, tôi đã thấy các cảnh báo trong các câu hỏi được liên kết.;)) – coppit

+0

Bạn có đang thay thế tệp 'classlist' bằng phiên bản đã sửa đổi của mình không? –

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