最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java中字符串去重的特性介紹

 更新時間:2015年07月10日 10:18:36   投稿:goldensun  
這篇文章主要介紹了Java中字符串去重的特性,是Java8中引入的一個新特性,至于是否真的用起來順手就見仁見智了...需要的朋友可以參考下

字符串在任何應用中都占用了大量的內存。尤其數包含獨立UTF-16字符的char[]數組對JVM內存的消耗貢獻最多——因為每個字符占用2位。

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

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


對于字符串去重,開發(fā)者考慮了大量的策略,但最終的實現采用了下面的方式:

無論何時垃圾回收器訪問了String對象,它會對char數組進行一個標記。它獲取char數組的hash value并把它和一個對數組的弱引用存在一起。只要垃圾回收器發(fā)現另一個字符串,而這個字符串和char數組具有相同的hash code,那么就會對兩者進行一個字符一個字符的比對。

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

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


那么該特性實際上是怎么工作的呢?首先,你需要剛剛發(fā)布的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);
  }
 }
}

這段代碼會執(zhí)行30個迭代之后報OutOfMemoryError。

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

-Xmx256m -XX:+UseG1GC -XX:+UseStringDeduplication -XX:+PrintStringDeduplicationStatistics

此時它已經可以運行更長的時間,而且在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]

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

上面的代碼段規(guī)定執(zhí)行了字符串去重,花了16ms的時間,查看了約 120 k 字符串。


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

在上述的案例中,所有的字符串都被去重了,在內存中移除了4.5MB的數據。

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

那么,字符串去重和字符串駐留相比又有什么差別呢?事實上,字符串去重和駐留看起來差不多,除了暫留的機制重用了整個字符串實例,而不僅僅是字符數組。


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

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

相關文章

  • java中URLencode、URLdecode及Base64加解密轉換

    java中URLencode、URLdecode及Base64加解密轉換

    本文主要介紹了java中URLencode、URLdecode及Base64加解密轉換,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2024-01-01
  • java動態(tài)代理詳解

    java動態(tài)代理詳解

    本文章要用很土的語言描述Java動態(tài)代理,力求更易被理解。Java是JDK5中新加的機制,大家都知道Spring是用Java的動態(tài)代理實現的,那這個動態(tài)代理是什么東東呢,首先他肯定是個代理,我們先講代理,把代理弄明白了,動態(tài)代理就好說了
    2014-02-02
  • 解決org.apache.ibatis.binding.BindingException:?Invalid?bound?statement?(not?found)問題(最新推薦)

    解決org.apache.ibatis.binding.BindingException:?Invalid?boun

    這篇文章主要介紹了解決org.apache.ibatis.binding.BindingException:?Invalid?bound?statement?(not?found)問題,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-05-05
  • Springboot中實現接口冪等性的4種方案小結

    Springboot中實現接口冪等性的4種方案小結

    本文主要介紹了Springboot中實現接口冪等性,包含數據庫的冪等,數據庫的冪等,Redis的冪等性和Token + 時間戳的冪等性,具有一定的參考價值,感興趣的可以了解一下
    2024-03-03
  • Spring?Batch實現批量處理

    Spring?Batch實現批量處理

    本文主要介紹了Spring?Batch進行批量處理,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-06-06
  • 淺談基于Token的WEB后臺認證機制

    淺談基于Token的WEB后臺認證機制

    這篇文章主要介紹了淺談基于Token的WEB后臺認證機制,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-12-12
  • Java封裝數組實現包含、搜索和刪除元素操作詳解

    Java封裝數組實現包含、搜索和刪除元素操作詳解

    這篇文章主要介紹了Java封裝數組實現包含、搜索和刪除元素操作,結合實例形式分析了java針對數組元素的查找、刪除、判斷等相關操作封裝與使用技巧,需要的朋友可以參考下
    2020-03-03
  • SpringBoot中Filter?bean如何添加到Servlet容器

    SpringBoot中Filter?bean如何添加到Servlet容器

    這篇文章主要介紹了SpringBoot中Filter bean是怎么被添加到Servlet容器中的,本文分步驟結合實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-08-08
  • Java 面向對象的特征解析與應用

    Java 面向對象的特征解析與應用

    Java 是面向對象的編程語言,對象就是面向對象程序設計的核心。所謂對象就是真實世界中的實體,對象與實體是一一對應的,也就是說現實世界中每一個實體都是一個對象,它是一種具體的概念
    2021-11-11
  • Java實例講解注解的應用

    Java實例講解注解的應用

    JAVA注解?Annotation(注解)是JDK1.5及以后版本引入的。它可以用于創(chuàng)建文檔,跟蹤代碼中的依賴性,甚至執(zhí)行基本編譯時檢查。注解是以‘@注解名’在代碼中存在的
    2022-06-06

最新評論

弥勒县| 武隆县| 麦盖提县| 石渠县| 武强县| 梧州市| 肇源县| 宜春市| 石泉县| 南木林县| 呼和浩特市| 万山特区| 客服| 阿克陶县| 固安县| 子洲县| 岳普湖县| 宁安市| 息烽县| 商水县| 定兴县| 晋宁县| 烟台市| 石棉县| 壶关县| 确山县| 永昌县| 伊金霍洛旗| 许昌市| 酒泉市| 玉环县| 龙陵县| 闽清县| 噶尔县| 勃利县| 蓬莱市| 汝南县| 凤凰县| 南岸区| 洛川县| 根河市|