亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > Java > 正文

Java中由substring方法引發的內存泄漏詳解

2024-07-13 10:15:32
字體:
來源:轉載
供稿:網友

內存溢出(out of memory ) :通俗的說就是內存不夠用了,比如在一個無限循環中不斷創建一個大的對象,很快就會引發內存溢出。

內存泄漏(leak of memory) :是指為一個對象分配內存之后,在對象已經不在使用時未及時的釋放,導致一直占據內存單元,使實際可用內存減少,就好像內存泄漏了一樣。

由substring方法引發的內存泄漏

substring(int beginIndex, int endndex )是String類的一個方法,但是這個方法在JDK6和JDK7中的實現是完全不同的(雖然它們都達到了同樣的效果)。了解它們實現細節上的差異,能夠更好的幫助你使用它們,因為在JDK1.6中不當使用substring會導致嚴重的內存泄漏問題。

1、substring的作用

substring(int beginIndex, int endIndex)方法返回一個子字符串,從父字符串的beginIndex開始,結束于endindex-1。父字符串的下標從0開始,子字符串包含beginIndex而不包含endIndex

String x= "abcdef";x= str.substring(1,3);System.out.println(x);

上述程序的輸出是“bc”

2、實現原理

String類是不可變變,當上述第二句中x被重新賦值的時候,它會指向一個新的字符串對象。然而,沒有準確說明的或者代表堆中發生的實際情況,當substring被調用的時候真正發生的才是這兩者的差別。

JDK6中的substring實現

String對象被當作一個char數組來存儲,在String類中有3個域:char[] value、int offset、int count,分別用來存儲真實的字符數組,數組的起始位置,String的字符數。由這3個變量就可以決定一個字符串。當substring方法被調用的時候,它會創建一個新的字符串,但是上述的char數組value仍然會使用原來父數組的那個value。父數組和子數組的唯一差別就是count和offset的值不一樣。

看一下JDK6中substring的實現源碼:

public String substring(int beginIndex, int endIndex) { if (beginIndex < 0) { throw new StringIndexOutOfBoundsException(beginIndex); } if (endIndex > count) { throw new StringIndexOutOfBoundsException(endIndex); } if (beginIndex > endIndex) { throw new StringIndexOutOfBoundsException(endIndex - beginIndex); } return ((beginIndex == 0) && (endIndex == count)) ? this : new String(offset + beginIndex, endIndex - beginIndex, value); //使用的是和父字符串同一個char數組value }
String(int offset, int count, char value[]) { this.value = value; this.offset = offset; this.count = count; }
String str = "abcdefghijklmnopqrst";String sub = str.substring(1, 3);str = null;

這段簡單的程序有兩個字符串變量str、sub。sub字符串是由父字符串str截取得到的,假如上述這段程序在JDK1.6中運行,我們知道數組的內存空間分配是在堆上進行的,那么sub和str的內部char數組value是公用了同一個,也就是上述有字符a~字符t組成的char數組,str和sub唯一的差別就是在數組中其實beginIndex和字符長度count的不同。在第三句,我們使str引用為空,本意是釋放str占用的空間,但是這個時候,GC是無法回收這個大的char數組的,因為還在被sub字符串內部引用著,雖然sub只截取這個大數組的一小部分。當str是一個非常大字符串的時候,這種浪費是非常明顯的,甚至會帶來性能問題,解決這個問題可以是通過以下的方法:

利用的就是字符串的拼接技術,它會創建一個新的字符串,這個新的字符串會使用一個新的內部char數組存儲自己實際需要的字符,這樣父數組的char數組就不會被其他引用,令str=null,在下一次GC回收的時候會回收整個str占用的空間。但是這樣書寫很明顯是不好看的,所以在JDK7中,substring 被重新實現了。

JDK7中的substring實現

在JDK7中改進了substring的實現,它實際是為截取的子字符串在堆中創建了一個新的char數組用于保存子字符串的字符。

查看JDK7中String類的substring方法的實現源碼:

public String substring(int beginIndex, int endIndex) { if (beginIndex < 0) { throw new StringIndexOutOfBoundsException(beginIndex); } if (endIndex > value.length) { throw new StringIndexOutOfBoundsException(endIndex); } int subLen = endIndex - beginIndex; if (subLen < 0) { throw new StringIndexOutOfBoundsException(subLen); } return ((beginIndex == 0) && (endIndex == value.length)) ? this : new String(value, beginIndex, subLen); }
public String(char value[], int offset, int count) { if (offset < 0) { throw new StringIndexOutOfBoundsException(offset); } if (count < 0) { throw new StringIndexOutOfBoundsException(count); } // Note: offset or count might be near -1>>>1. if (offset > value.length - count) { throw new StringIndexOutOfBoundsException(offset + count); } this.value = Arrays.copyOfRange(value, offset, offset+count); }

Arrays類的copyOfRange方法:

public static char[] copyOfRange(char[] original, int from, int to) { int newLength = to - from; if (newLength < 0)  throw new IllegalArgumentException(from + " > " + to); char[] copy = new char[newLength]; //是創建了一個新的char數組 System.arraycopy(original, from, copy, 0,    Math.min(original.length - from, newLength)); return copy; }

可以發現是去為子字符串創建了一個新的char數組去存儲子字符串中的字符。這樣子字符串和父字符串也就沒有什么必然的聯系了,當父字符串的引用失效的時候,GC就會適時的回收父字符串占用的內存空間。

總結

以上就是本文關于Java中由substring方法引發的內存泄漏詳解的全部內容,希望對大家有所幫助。感興趣的朋友可以繼續參閱本站其他相關專題,如有不足之處,歡迎留言指出。感謝朋友們對本站的支持!


注:相關教程知識閱讀請移步到JAVA教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
成人午夜黄色影院| 91国产美女视频| 日韩欧美成人区| 美女扒开尿口让男人操亚洲视频网站| 国产精品视频资源| 亚洲护士老师的毛茸茸最新章节| 日韩在线免费观看视频| 一区二区三区回区在观看免费视频| 国产精品久久久久久久久久久不卡| 日韩三级影视基地| 日韩av在线一区| 亚洲一区二区三区视频播放| 国产精品老女人精品视频| 国产伊人精品在线| 久久激情视频免费观看| 亚洲欧美国产高清va在线播| 国产视频精品一区二区三区| xxx成人少妇69| 日韩美女在线看| 91日韩在线播放| 久久久伊人日本| 欧美精品激情在线| 久久久久久久久国产精品| 视频在线观看一区二区| 91精品91久久久久久| 欧美一级片久久久久久久| 一本色道久久综合狠狠躁篇怎么玩| 亚洲欧美日韩国产中文| 久久综合免费视频| 2019中文字幕在线免费观看| 亚洲成人激情图| 欧美色xxxx| 欧美大片免费看| 伊人久久五月天| 97国产suv精品一区二区62| 午夜精品久久久久久99热| 在线精品91av| 亚洲欧美激情另类校园| 青青草原一区二区| 九九热99久久久国产盗摄| 国产99久久精品一区二区永久免费| 亚洲激情国产精品| 欧美日韩人人澡狠狠躁视频| 国内精品久久影院| 久久伊人精品一区二区三区| 国产精品久久不能| 久久91亚洲人成电影网站| 日韩最新中文字幕电影免费看| 欧美人成在线视频| 性色av香蕉一区二区| 九九热视频这里只有精品| 日韩欧美一区二区三区久久| 久久91亚洲精品中文字幕| 亚洲精品一区久久久久久| 亚洲xxx自由成熟| 国产精品一区二区性色av| 日韩av在线直播| 亚洲美女在线观看| 2019中文字幕全在线观看| 国产成人小视频在线观看| 国产偷国产偷亚洲清高网站| 亚洲黄色片网站| 精品视频一区在线视频| 国产九九精品视频| 欧美成人精品不卡视频在线观看| 在线观看欧美日韩国产| 国产精品极品尤物在线观看| 欧美另类69精品久久久久9999| 日韩欧美第一页| 亚洲人成网站在线播| 欧美成人性生活| 国产精品午夜一区二区欲梦| 国产精品第100页| 精品国产成人av| 亚洲第一区中文字幕| 疯狂蹂躏欧美一区二区精品| 亚洲欧美中文日韩v在线观看| 国产午夜精品一区理论片飘花| 亚洲欧美激情在线视频| 欧美一级大片在线观看| 国产亚洲精品高潮| 欧美黑人巨大xxx极品| 亚洲精品中文字幕av| 欧美老妇交乱视频| 欧美日本啪啪无遮挡网站| 日本亚洲欧美成人| 日韩在线国产精品| 亚洲国产日韩欧美综合久久| 亚洲a一级视频| 97视频在线观看视频免费视频| 91在线视频免费| 国产成人鲁鲁免费视频a| 成人免费大片黄在线播放| 欧美一区三区三区高中清蜜桃| 日本国产精品视频| 亚洲电影免费观看高清完整版在线观看| 久久久国产精品x99av| 国产精品自拍小视频| 亚洲欧美日韩久久久久久| 欧美日韩视频在线| 77777少妇光屁股久久一区| 欧美综合国产精品久久丁香| 久久免费视频在线| 91午夜在线播放| 亚洲视频网站在线观看| 欧美日韩国产丝袜另类| 欧美视频在线免费| 国产又爽又黄的激情精品视频| 最新国产成人av网站网址麻豆| 日本最新高清不卡中文字幕| 亚洲国产日韩欧美在线99| 国产手机视频精品| 26uuu另类亚洲欧美日本老年| 黄色精品在线看| 久久久噜噜噜久噜久久| 亚洲欧美成人在线| 欧美不卡视频一区发布| 欧美激情精品久久久久久久变态| 亚洲精品成人久久久| 欧美激情亚洲另类| 亚洲欧美日韩中文在线制服| 亚洲欧美日韩区| 伊人久久免费视频| 亚洲精品久久视频| 51久久精品夜色国产麻豆| 日韩亚洲欧美成人| 亚洲精品成人免费| 色综合色综合久久综合频道88| 91在线免费观看网站| 久久免费福利视频| 日韩av在线天堂网| 91久久国产综合久久91精品网站| 日韩欧美在线视频免费观看| 欧美精品一二区| 亚洲国产91精品在线观看| xvideos亚洲| 777777777亚洲妇女| 精品视频在线播放色网色视频| 日韩成人xxxx| 国产精品爱啪在线线免费观看| 亚洲最大的网站| 国产在线观看91精品一区| 爽爽爽爽爽爽爽成人免费观看| 日本一区二区在线免费播放| 2021国产精品视频| 91久久久久久久一区二区| 国产ts人妖一区二区三区| 福利一区视频在线观看| 国产精品极品在线| 26uuu另类亚洲欧美日本老年| 国产一区二区三区在线看| 欧美日韩在线第一页| 精品一区二区三区电影| 欧美一区在线直播| 色偷偷偷亚洲综合网另类| 视频直播国产精品| 色婷婷av一区二区三区在线观看| 久久久久这里只有精品| 日韩精品福利在线| 日韩网站在线观看| 国产精品国产亚洲伊人久久| 亚洲综合精品一区二区| 国产精品视频一区二区三区四| 91亚洲va在线va天堂va国|