jdk8读取文件_JDK 7和JDK 8中大行读取速度较慢的原因
jdk8讀取文件
我早些時(shí)候發(fā)布了博客文章Reading Large Lines Slower in JDK 7和JDK 8,并且在描述該問(wèn)題的文章上有一些有用的評(píng)論 。 這篇文章提供了更多解釋,說(shuō)明為何該文章中演示的文件讀取(并由Ant的LineContainsRegExp使用 )在Java 7和Java 8中比在Java 6中這么慢。
X Wang的帖子JDK 6和JDK 7中的substring()方法描述了如何在JDK 6和JDK 7之間更改String.substring() 。Wang在該帖子中寫(xiě)道,JDK 6 substring() “創(chuàng)建了一個(gè)新字符串,但字符串的值仍指向堆中相同的[backing char]數(shù)組。” 他與JDK 7方法形成對(duì)比,“在JDK 7中,substring()方法實(shí)際上在堆中創(chuàng)建了一個(gè)新數(shù)組。”
Wang的帖子對(duì)于理解Java 6和Java 7之間String.substring()的區(qū)別非常有用。對(duì)該帖子的評(píng)論也很有見(jiàn)地。 這些評(píng)論包括我很欣賞的觀(guān)點(diǎn) ,“我會(huì)說(shuō)'不同'而不是'改善'。” 也有關(guān)于JDK 7如何避免 JDK 6中可能發(fā)生的潛在內(nèi)存泄漏的解釋 。
StackOverflow線(xiàn)程Java 7字符串–子字符串的復(fù)雜性解釋了更改的動(dòng)機(jī),并引用了JDK-4513622錯(cuò)誤:(str)保留字段的子字符串會(huì)阻止對(duì)象的GC 。 該錯(cuò)誤指出:“ [發(fā)生OutOfMemory錯(cuò)誤,因?yàn)槿绻{(diào)用者在對(duì)象中存儲(chǔ)字段的子字符串,則對(duì)象不會(huì)被垃圾回收。” 該錯(cuò)誤包含演示此錯(cuò)誤發(fā)生的示例代碼。 我在這里修改了該代碼:
/*** Minimally adapted from Bug JDK-4513622.** {@link http://bugs.java.com/view_bug.do?bug_id=4513622}*/ public class TestGC {private String largeString = new String(new byte[100000]);private String getString(){return this.largeString.substring(0,2);}public static void main(String[] args){java.util.ArrayList<String> list = new java.util.ArrayList<String>();for (int i = 0; i < 1000000; i++){final TestGC gc = new TestGC();list.add(gc.getString());}} }下一個(gè)屏幕快照演示了用Java 6(jdk1.6是可執(zhí)行Java啟動(dòng)程序路徑的一部分)和Java 8(主機(jī)上的默認(rèn)版本)執(zhí)行的最后一個(gè)代碼段(從Bug JDK-4513622改編而成)。 如屏幕快照所示,在Java 6中運(yùn)行代碼時(shí)拋出OutOfMemoryError ,而在Java 8中運(yùn)行時(shí)不拋出OutOfMemoryError 。
換句話(huà)說(shuō),當(dāng)對(duì)冗長(zhǎng)的Java字符串執(zhí)行String.substring時(shí),Java 7中的更改修復(fù)了潛在的內(nèi)存泄漏,但以性能影響為代價(jià)。 這意味著使用String.substring (包括Ant的LineContainsRegExp)來(lái)處理很長(zhǎng)的行的任何實(shí)現(xiàn)都可能需要更改以不同的方式實(shí)現(xiàn),或者在從Java 6遷移到Java 7或更高版本時(shí)處理很長(zhǎng)的行時(shí)應(yīng)避免使用。
一旦知道了問(wèn)題(在這種情況下更改String.substring實(shí)現(xiàn)),就可以更輕松地在線(xiàn)找到有關(guān)正在發(fā)生的事情的文檔(感謝提供了使這些資源易于查找的注釋)。 JDK-4513622的重復(fù)錯(cuò)誤包含提供額外詳細(xì)信息的內(nèi)容。 這些錯(cuò)誤是JDK-4637640:由于String.substring()實(shí)現(xiàn)而導(dǎo)致的內(nèi)存泄漏和JDK-6294060:使用substring()導(dǎo)致了內(nèi)存泄漏 。 其他相關(guān)的在線(xiàn)資源包括Java 7中對(duì)String.substring的更改 (其中包括對(duì)String.intern()的引用-有更好的方法 ), Java 6與Java 7:當(dāng)實(shí)現(xiàn)很重要時(shí) ,以及受到高度評(píng)價(jià)(超過(guò)350條注釋) Reddit線(xiàn)程TIL Oracle更改了Java 7 Update 6中的內(nèi)部String表示,從而將子字符串方法的運(yùn)行時(shí)間從常量更改為N。
用Java 1.7.0_06編寫(xiě)的“更改為String內(nèi)部表示形式”一文很好地回顧了此更改,并總結(jié)了原始問(wèn)題,修復(fù)程序以及與該修復(fù)程序相關(guān)的新問(wèn)題:
現(xiàn)在您可以忘記上面描述的內(nèi)存泄漏,并且永遠(yuǎn)不再使用新的String(String)構(gòu)造函數(shù)。 缺點(diǎn)是,您現(xiàn)在必須記住String.substring現(xiàn)在具有線(xiàn)性復(fù)雜度,而不是恒定的復(fù)雜度。
翻譯自: https://www.javacodegeeks.com/2015/01/reason-for-slower-reading-of-large-lines-in-jdk-7-and-jdk-8.html
jdk8讀取文件
總結(jié)
以上是生活随笔為你收集整理的jdk8读取文件_JDK 7和JDK 8中大行读取速度较慢的原因的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 物业居民备案管理办法(物业居民备案)
- 下一篇: 搜狗输入linux(搜狗输入 linux