搜尋
首頁Javajava教程java 8 Update 20 的新特性 —— 字串去重

 字串在任何應用中都佔用了大量的記憶體。尤其數包含獨立UTF-16字元的char[]陣列對JVM記憶體的消耗貢獻最多-因為每個字元佔用2位元。

  記憶體的30%被字串消耗其實是很常見的,不僅是因為字串是與我們互動的最好的格式,而且是由於流行的HTTP API使用了大量的字串。使用Java 8 Update 20,我們現在可以接觸到一個新特性,叫做字串去重,該特性需要G1垃圾回收器,該垃圾回收器預設是關閉的。

  字串去重利用了字串內部實際上是char數組,並且是final的特性,所以JVM可以任意的操縱他們。

  對於字串去重,開發者考慮了大量的策略,但最終的實現採用了下面的方式:

  無論何時垃圾回收器訪問了String對象,它會對char數組進行一個標記。它取得char數組的hash value並把它和一個對數組的弱引用存在一起。只要垃圾回收器發現另一個字串,而這個字串和char陣列有相同的hash code,那麼就會對兩者進行一個字元一個字元的比對。

  如果他們恰好匹配,那麼一個字串就會被修改,指向第二個字串的char數組。第一個char數組就不再被引用,也就可以被回收了。

  這整個過程當然帶來了一些開銷,但是被很緊實的上限控制了。例如,如果一個字元未發現有重複,那麼一段時間之內,它會不再被檢查。

  那麼該特性實際上是怎麼運作的呢?首先,你需要剛發布的Java 8 Update 20,然後按照這個設定: -Xmx256m -XX:+UseG1GC 去執行下列的程式碼:

public class LotsOfStrings {
   
  private static final LinkedList<String> LOTS_OF_STRINGS = new LinkedList<>();
   
  public static void main(String[] args) throws Exception {
    int iteration = 0;
    while (true) {
      for (int i = 0; i < 100; i++) {
        for (int j = 0; j < 1000; j++) {
          LOTS_OF_STRINGS.add(new String("String " + j));
        }
      }
      iteration++;
      System.out.println("Survived Iteration: " + iteration);
      Thread.sleep(100);
    }
  }
}

這段程式碼會執行30個迭代之後報OutOfMemoryError。

  現在,開啟字串去重,使用如下配置去跑上述程式碼:

  -Xmx256m -XX:+UseG1GC -XX:+UseStringDeduplication -XX:+PrintStringDedupliliStatistics🀎而且在50次迭代之後才終止。

  JVM現在同樣打印出了它做了什麼,讓我們一起看一下:

[GC concurrent-string-deduplication, 4658.2K->0.0B(4658.2K), avg 99.6%, 0.0165023 secs]
   [Last Exec: 0.0165023 secs, Idle: 0.0953764 secs, Blocked: 0/0.0000000 secs]
      [Inspected:          119538]
         [Skipped:              0(  0.0%)]
         [Hashed:          119538(100.0%)]
         [Known:                0(  0.0%)]
         [New:             119538(100.0%)   4658.2K]
      [Deduplicated:       119538(100.0%)   4658.2K(100.0%)]
         [Young:              372(  0.3%)     14.5K(  0.3%)]
         [Old:             119166( 99.7%)   4643.8K( 99.7%)]
   [Total Exec: 4/0.0802259 secs, Idle: 4/0.6491928 secs, Blocked: 0/0.0000000 secs]
      [Inspected:          557503]
         [Skipped:              0(  0.0%)]
         [Hashed:          556191( 99.8%)]
         [Known:              903(  0.2%)]
         [New:             556600( 99.8%)     21.2M]
      [Deduplicated:       554727( 99.7%)     21.1M( 99.6%)]
         [Young:             1101(  0.2%)     43.0K(  0.2%)]
         [Old:             553626( 99.8%)     21.1M( 99.8%)]
   [Table]
      [Memory Usage: 81.1K]
      [Size: 2048, Min: 1024, Max: 16777216]
      [Entries: 2776, Load: 135.5%, Cached: 0, Added: 2776, Removed: 0]
      [Resize Count: 1, Shrink Threshold: 1365(66.7%), Grow Threshold: 4096(200.0%)]
      [Rehash Count: 0, Rehash Threshold: 120, Hash Seed: 0x0]
      [Age Threshold: 3]
   [Queue]
      [Dropped: 0]

為了方便,我們不需要自己去計算所有數據的加和,使用方便的總計就可以了。

  上面的程式碼段規定執行了字串去重,花了16ms的時間,查看了約 120 k 字串。

  上面的特性是剛推出的,意味著可能並沒有被全面的審視。具體的資料在實際的應用中可能看起來有差別,尤其是那些應用程式中字串被多次使用和傳遞,因此一些字串可能被跳過或早就有了hashcode(正如你可能知道的那樣,一個String的hash code是被懶載入的)。

  在上述的案例中,所有的字串都被去重了,在記憶體中移除了4.5MB的資料。

  [Table]部分給出了有關內部追蹤表的統計信息,[Queue]則列出了有多少對去重的請求由於負載被丟棄,這也是開銷減少機制中的一部分。

  那麼,字串去重和字串駐留相比又有什麼差別呢?我部落格上有一篇文章,名叫how great String Interning is for memory efficiency 。事實上,字串去重和駐留看起來差不多,除了暫留的機制重用了整個字串實例,而不僅僅是字元陣列。

  JDK Enhancement Proposal 192的創造者的爭論點在於開發者們常常不知道將駐留字符串放在哪裡合適,或者是合適的地方被框架所隱藏.就像我寫的那樣,當碰到復制字串(像國家名字)的時候,你需要一些常識.字串去重,對於在同一個JVM中的應用程式的字串複製也有好處,同樣包括像XML Schemas,urls以及jar名字等一般認為不會出現多次的字串.

  當字串駐留發生在應用程式執行緒中的時候,垃圾回收非同步並發處理時,字串去重也不會增加運行時的消耗.這也解釋了,為什麼我們會在上面的程式碼中發現Thread.sleep().如果沒有sleep會給GC增加太多的壓力,這樣字串去重根本就不會發生.但是,這只是範例程式碼才會出現的問題.實際的應用程式,常常會在運行字串去重的時候使用幾毫秒的時間.

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
Java仍然是基於新功能的好語言嗎?Java仍然是基於新功能的好語言嗎?May 12, 2025 am 12:12 AM

Javaremainsagoodlanguageduetoitscontinuousevolutionandrobustecosystem.1)Lambdaexpressionsenhancecodereadabilityandenablefunctionalprogramming.2)Streamsallowforefficientdataprocessing,particularlywithlargedatasets.3)ThemodularsystemintroducedinJava9im

是什麼使Java很棒?關鍵特徵和好處是什麼使Java很棒?關鍵特徵和好處May 12, 2025 am 12:11 AM

Javaisgreatduetoitsplatformindependence,robustOOPsupport,extensivelibraries,andstrongcommunity.1)PlatformindependenceviaJVMallowscodetorunonvariousplatforms.2)OOPfeatureslikeencapsulation,inheritance,andpolymorphismenablemodularandscalablecode.3)Rich

前5個Java功能:示例和解釋前5個Java功能:示例和解釋May 12, 2025 am 12:09 AM

Java的五大特色是多態性、Lambda表達式、StreamsAPI、泛型和異常處理。 1.多態性讓不同類的對象可以作為共同基類的對象使用。 2.Lambda表達式使代碼更簡潔,特別適合處理集合和流。 3.StreamsAPI高效處理大數據集,支持聲明式操作。 4.泛型提供類型安全和重用性,編譯時捕獲類型錯誤。 5.異常處理幫助優雅處理錯誤,編寫可靠軟件。

Java的最高功能如何影響性能和可伸縮性?Java的最高功能如何影響性能和可伸縮性?May 12, 2025 am 12:08 AM

java'stopfeatureSnificallyenhanceItsperformanCandScalability.1)對象 - 方向clincipleslike-polymormormormormormormormormormormormorableableflexibleandscalablecode.2)garbageCollectionAutectionAutoctionAutoctionAutoctionAutoctionAutoctionAutoMenateMememorymanateMmanateMmanateMmanagementButCancausElatemention.3)

JVM內部:深入Java虛擬機JVM內部:深入Java虛擬機May 12, 2025 am 12:07 AM

JVM的核心組件包括ClassLoader、RuntimeDataArea和ExecutionEngine。 1)ClassLoader負責加載、鏈接和初始化類和接口。 2)RuntimeDataArea包含MethodArea、Heap、Stack、PCRegister和NativeMethodStacks。 3)ExecutionEngine由Interpreter、JITCompiler和GarbageCollector組成,負責bytecode的執行和優化。

什麼是使Java安全安全的功能?什麼是使Java安全安全的功能?May 11, 2025 am 12:07 AM

Java'ssafetyandsecurityarebolsteredby:1)strongtyping,whichpreventstype-relatederrors;2)automaticmemorymanagementviagarbagecollection,reducingmemory-relatedvulnerabilities;3)sandboxing,isolatingcodefromthesystem;and4)robustexceptionhandling,ensuringgr

必不可少的Java功能:增強您的編碼技巧必不可少的Java功能:增強您的編碼技巧May 11, 2025 am 12:07 AM

Javaoffersseveralkeyfeaturesthatenhancecodingskills:1)對象 - 方向 - 方向上的allowslowsmodelowsmodelingreal-worldentities

JVM最完整的指南JVM最完整的指南May 11, 2025 am 12:06 AM

thejvmisacrucialcomponentthatrunsjavacodebytranslatingitolachine特定結構,影響性能,安全性和便攜性。 1)theclassloaderloader,links andinitializesClasses.2)theexecutionEngineExecutionEngineExecutionEngineExecuteNexeCuteByteCuteByteCuteByTecuteByteCuteByteCuteBytecuteBytecuteByteCoDeinintolachineinstructionsions.3)Memo.3)Memo

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

WebStorm Mac版

WebStorm Mac版

好用的JavaScript開發工具

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

mPDF

mPDF

mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

PhpStorm Mac 版本

PhpStorm Mac 版本

最新(2018.2.1 )專業的PHP整合開發工具