2011-05-09 65 views
2

將類打包爲Jar文件而不僅僅是運行未打包的類時,性能會如何?比如說你有一個很大的應用程序,如果需要從檔案中提取很多文件,這會減慢你的應用程序嗎?使用JAR文件打擊性能

回答

8

不,它不會。這些類被加載到內存中並從那裏使用。

可能它可能會減慢啓動時間,但這可以忽略不計。另外,如果您在運行時積極地加載和卸載類,可能會有所不同,但仍然可以忽略不計。

底線是:出於性能原因,您不應該拆開罐子。

+0

僅當需要時才加載類是不正確的?當然,這不是啓動時的一次性負載? – Brian 2014-07-29 18:33:03

2

啓動時間可能有點長取決於壓縮,但一旦它完全運行應該沒有性能損失

1

取決於讀取壓縮數據+解壓是否需要比所用的時間讀更多的時間未壓縮的數據,然後才啓動。

3

從爆炸目錄加載類不會導致任何性能優勢。如果是這種情況,那麼在運行分解JAR時,幾個Java應用程序(特別是Java EE應用程序服務器)會看到性能優勢。

缺乏性能優勢的更科學的原因是JAR通常是壓縮的,可以從磁盤上非常特定的一組扇區訪問,這在爆炸JAR中不太可能發生。這也意味着使用爆炸JAR中的類時,性能受到很大影響。

此外,類加載操作通常只執行一次。除非永久性世代需要經歷幾個階段的裝載和卸載階段(對於一個規模較小的永久世代),階級負載不太可能是導致性能不佳的一個因素。

0

不,它不會。在大型應用中,效果可能是負面的。典型的I/O開銷高於未解壓縮的增益。此外,罐子有一個索引,可以提高重複訪問的速度。在文件系統中遍歷目錄樹的成本通常高於訪問索引的jar。

只要您的操作系統開始將文件緩存在內存中,性能問題就會消失。從Java 6開始,JRE將首先在Windows上檢查緩存。如果緩存溫度較高,則需要幾分鐘才能加載的應用程序將在10-20秒內加載。目錄中的jar和* .class-files的效果應該相似。請記住,不要將此效應與您正在進行的優化相混淆,並始終在冷啓動時進行測量。

0

這裏有一個交易,但大多數情況下,您想使用JAR文件。

如果您只加載一個類,則可以將它加載得比文件快,而不是從JAR文件中讀出。但是,你可能會花更多的時間去尋找這門課,特別是如果它有很多目錄,並且還有很多其他的課程。

如果您正在加載很多類,那麼加載它們將會是一個巨大的損失:將會分開打開,讀取和關閉每個文件的步驟,而您只需要一次從JAR文件讀取。 (假設你在類加載之間保持JAR打開;如果你正在執行多個類加載,爲每個類加載重新打開JAR將是一個巨大的問題。)

更詳細,對於類加載,這裏的兩個策略是:

(1)班暴露在磁盤上。 (2)打包在JAR文件中的類。

對於(1),將根目錄下移到目標類會有一些成本。這可以通過增量和按需完成,也可以在整個目錄樹中進行。如果需要列出很多目錄,那麼這個成本就會相當大。

也是(1),有開放和閱讀各個類的成本。對於一個類而言,這比打開JAR的成本要低,但對於許多類而言,由於打開單個文件的額外開銷,成本最終會變得更大。

對於(2),初始JAR打開需要額外的開銷,它將讀取JAR條目的索引。這將與JAR中的條目數成比例。

對於(2),當讀取類加載的單個資源時,將會有尋找,解壓縮和驗證類資源的成本。減壓通常是洗滌,因爲壓縮減少了讀取時間,但增加了減壓步驟。驗證是額外的,但可以關閉。

對於(1)的網絡,如果讀取整個目錄,那麼在(2)打開JAR的成本要高得多。在(1)中,如果以某種方式增量讀取目錄,那麼最初可能會更快,但讀取單個類的成本最終會大於(2)的JAR讀取成本。 「最終」可能不會是很多班級負荷。

爲了比較兩種情況,有哪些值得思索這些額外的問題:

(1),具有磁盤上的文件的開銷比原始數據存儲方面具有隻是一個JAR文件的要高得多和文件系統開銷。 (2)作爲單個文件訪問類會佔用多個文件句柄;從JAR訪問類將只使用一個。 (3)由於必須進行目錄複製,或者進行打包,複製和解壓縮,所以傳輸類成爲一件繁雜的工作。複製許多單個文件比複製單個JAR文件要昂貴得多。

(4)使用JAR可讓您使用構建到類加載APIS中的JAR簽名功能。

在應用程序服務器空間中,當查看WAR文件下的類是如何打包時,(1)和(2)之間的選擇會產生影響。也就是說,類可以打包在WEB-INF/classes下,或者打包在WEB-INF/lib下的JAR文件中。如果應用程序服務器從正在運行的服務器上解壓WAR文件以進行訪問,那麼在WEB-INF/classes下有類會增加非常大的開銷。應用程序服務器通常更喜歡將這些類保存在JAR文件中。