JDK6
中的subString
方法会存在内存泄露
问题,是由于源字符串中的value
数组不会被GC
回收。
看到一篇文章(http://www.cnblogs.com/hxy520...),里面有如下代码,说在JDK6
下会报内存溢出
的错误。请问下,为什么会产生?list
的每次add
不是只加一点点内存占用么?
public class SubMain { private String strs = new String(new byte[100000]); String getString() { return this.strs.substring(0, 2); } public static void main(String[] args) { List list = new ArrayList(); SubMain sub = new SubMain(); for (int i = 0; i < 1000000; i++) { list.add(sub.getString()); } } } /*Exception in thread "main" java.lang.OutOfMemoryError: Java heap space at java.lang.StringCoding$StringDecoder.decode(StringCoding.java:133) at java.lang.StringCoding.decode(StringCoding.java:173) at java.lang.StringCoding.decode(StringCoding.java:185) at java.lang.String.(String.java:570) at java.lang.String.(String.java:593) at com.jd.o2o.substring.SubMain.(SubMain.java:8) at com.jd.o2o.substring.SubMain.main(SubMain.java:18)*/
其他参考文章:http://blog.csdn.net/longzuyu...,
http://www.wtoutiao.com/p/jfc...
前の子供用シューズでも、jdk1.6 メソッドでも、あなたが言及したメモリ リークの問題が発生しないことが非常に明確になりました。
メモリ不足の理由は、
1000000
new String(new byte[100000])
オブジェクトを適用するのに十分なメモリがないためです。1000000
个new String(new byte[100000])
对象。还有,按照你的逻辑来实现的话,
また、JDK1.6
的实现方式绝对是占用更少内存的,因为array
是引用类型。即便你循环1000000
次substring
,在String
对象中的char[] value
也是同一个对象,而JDK1.7
使用Arrays.copy
的方式实现,那你每一次substring
就将会生成一个新的char[] value
array
は参照型であるため、ロジックに従って実装された場合、JDK1.6
の実装は確実にメモリ占有量が少なくなります。1000000
回substring
をループしたとしても、String
オブジェクトのchar[] value
は同じオブジェクトです。JDK1.7
はArrays.copy
を使用して実装されており、substring
値ごとに新しいchar[] を生成します。コード>インスタンス。
まず for ループの外で
java SubMain sub = new SubMain();
を初期化する必要があります。for ループで毎回ヒープ上に SubMain を作成するため、各 SubMain は少なくとも 100k を占有し、それを 1,000,000 回繰り返すことになり、100G のヒープ領域が必要になります。同時に、SubMain への参照はリストに保存され、gc もフル gc もそれを再利用できず、確実にメモリがオーバーフローします。
同時に、メモリ割り当てについて議論するときは、少なくとも仮想マシン構成の -Xms、-Xmx、-Xmn、-XX:SurvivorRatio を提供してください。
この質問は非常に興味深いもので、私はそれを調べて知りました。著者の理解では、subString はせいぜい元の文字列メモリをリサイクルせず、リストのループによってメモリが少しずつ増加するだけです。時間。後でプログラムを注意深く見てみましょう:
リーリーstrings は SubMain のインスタンス変数であり、SubMain はループによって 1,000,000 回インスタンス化されているため、結果は想像できます...
さらに、この問題は JDK7 update6 で修正されました。
リーリー古いバージョンの JDK の場合は、次の方法を使用できます:
List は常にヒープ メモリへの参照を保持し、メモリがオーバーフローしないようにしてください。