0 0

String的substring方法. 难道是JAVA的bug?10

前几天写个小东西有个大问题。
使用java获取网页的源代码截东西。后来发现内存光涨不降。

发现String.substring中内容如果过大就有问题。
后来使用
String content = //获取网页内容 最好大一点
String temp = content.subString(0, 10);
String result = new String(temp);

return result;

如果直接返回temp。。。内存就有好瞧的。。大家可以试试下面的代码。基本上一分钟就over了。。最好用jconsole看效果。 呵呵。 如果是我其它的地方写错了。 请大家指正了。

验证程序 HttpClientUtil就是一取网页内容的。可以用别的替代。:
public class Test {

/**
* @param args
*/
public static void main(String[] args) {

String s1 = "http://finance.sina.com.cn/realstock/company/sz000831/nc.shtml";

List<String> s = new ArrayList<String>();
while(true){
String source = HttpClientUtil.getGetResponseWithHttpClient(s1, "gb2312");
String temp = source.substring(0, 10);
s.add(temp);
//s.add(new String(temp));
}

}

}


问题补充:
while(true){//这里的true是我特意加的。为的是延长时间来看到问题的出现。呵呵。 评论的那几位如果有空,请照着试一下就知道我说的情况了。 问题不在这个while的死循环。。。

问题补充:
我这个问题关心的是 使用subString后带来的内存问题。。。即便是使用 StringBuffer,在截取字符串的时候,还是要用 subString吧。
问题补充:
to: playfish
如果使用 s.add(new String(temp)); 就没任何问题。。。内存情况良好。

to: yourgame
呵呵,不清楚为什么你那里为什么会OK。
问题补充:
to sdh5724 :
我的代码是为了证明内存的只往上涨。。当然,你也可以说我的内存上涨是因为死循环造成的。 但使用 s.add(temp); 和 s.add(new String(temp)); 所造成的内存上升幅度则是有大区别。 如果你有空可以跑一下试试。

“以后能不能不用死循环来提问?

知道一秒要执行多少次么.........”

你跑一下就知道一秒执行多少次了。。。呵呵。 你的网络能有多快? 那是去取网页内容的。 我又不是多线程在跑。。。

另: 我也上传的内存使用情况的图片。 幅度不是一般的大。
问题补充:
谢谢 RednaxelaFX 的回答。应该是正解了。

同时也谢谢 playfish 。

不过,好像不能把分拆开吧。 我只好都给 RednaxelaFX  了
2009年3月25日 11:51
  • 大小: 79.9 KB
  • 大小: 87.4 KB

10个答案 按时间排序 按投票排序

0 0

采纳的答案

楼主的无限循环本来就是用来演示内存占用量的问题,是by-design的
用ArrayList来保存那些String显然不是个好做法,因为掩盖了楼主更关心的问题:substring()问题。

正好最近读帖的时候才有人提到过这个问题

James Watson 写道
Again I don't know C#, but one big gotcha with Strings in Java is that when you substring a large string, the underlying array is shared between the old String and the new String. So your original String object is released and GC'd but the underlying char array is not. If you have lots of big Strings, it looks like your Strings are not being GC'd because the array is the bulk of the memory used by the String. If C# Strings work the same way, I'd give you even odds that that was your problem.

楼主遇到的正好就是这个问题:使用substring()的时候,底下的字符数组的共享的,所以很可能会有String对象看来没有被释放到导致泄漏。嘛。

2009年3月25日 12:33
0 0


嗯,看来RednaxelaFX 的回答是正解

引用
使用substring()的时候,底下的字符数组的共享的,所以很可能会有String对象看来没有被释放到导致泄漏。


如果你的测试结果是这样的话,那说明你重新new String新建对象后原来的2个对象才会被GC回收释放掉.

2009年3月25日 13:05
0 0

以后能不能不用死循环来提问?

知道一秒要执行多少次么.........

2009年3月25日 12:54
0 0


lz说的应该没有错,但是这个应该不是bug

substring会创建一个新的string对象.内存自然就涨.你不断的循环执行,对象不断创建,而且你用list来保存,这些对象没有被销毁,越来越多,导致over.

如果想深入了解一下可以看下jdk的源代码,在你的JDK的安装目录下的src.zip里面解压出来看看里面的源代码.

2009年3月25日 12:26
0 0

if(source == null || source.length() <= 0){
   return;
}

这不会执行到的吧。

HttpClientUtil.getGetResponseWithHttpClient 不是类似Stream那样 read后,就变小一些的。

2009年3月25日 12:19
0 0

你把 HttpClientUtil 这个类给我 Q3990995

2009年3月25日 12:07
0 0

while(true){
String source = HttpClientUtil.getGetResponseWithHttpClient(s1, "gb2312");
if(source == null || source.length() <= 0){
   return;
}
String temp = source.substring(0, 10);
s.add(temp);
//s.add(new String(temp));

}

2009年3月25日 11:59
0 0

不过你这里很明显是个死循环

while(true){
String source = HttpClientUtil.getGetResponseWithHttpClient(s1, "gb2312");
String temp = source.substring(0, 10);
s.add(temp);
//s.add(new String(temp));
}

2009年3月25日 11:58
0 0

用StringBuffer 代替 效率高

2009年3月25日 11:57
0 0

while(true){
}

死循环吗?

2009年3月25日 11:51

相关推荐

    Java substring方法实现原理解析

    Java substring方法是一种常用的字符串操作方法,它可以截取字符串并返回指定范围内的内容。在 Java 中,substring 方法的实现原理是不同的版本的 JDK 中实现方式各不相同。了解这些差异可以帮助我们更好地使用 ...

    java常见错误.pdf

    例如,使用substring()方法时,起始或结束索引超出了字符串的长度,或者使用charAt()方法访问的索引不存在,都会引起这种异常。 4. java.lang.NoClassDefFoundError 当Java虚拟机或类加载器尝试加载类定义时,如果...

    编程语言java常见错误.pdf

    避免方法是确保索引值在字符串的实际长度范围内: ```java if (s_all_power.length() &gt; 4) { String s_access_power = s_all_power.substring(3, 4); } ``` 4. java.lang.NoClassDefFoundError(类定义找不到...

    Java基础PPT讲解.rar

    9. **字符串处理**:String类是不可变的,了解它的常用方法,如concat、substring、indexOf、replace等。 10. **泛型**:泛型引入了类型参数的概念,提高了代码的类型安全性和重用性。理解泛型类、泛型方法和通配符...

    一个用java做的简单的成绩管理系统

    此程序是我的Java老师给我们做的家庭作业,我大概花了一天的时间终于把它做完了. 程序说明: 功能:可以录入和查询成绩 注意:由于数据保存在文本文件中,所以存在一些问题.比如不易维护,容易出问题,请确保正确操作. bug ...

    java常见疑惑与陷阱

    `equals()`方法是用来比较两个对象是否相等的标准方法。然而,在实际开发中,我们常常会遇到一些特殊情况,如自定义类的`equals()`实现问题。 **示例:** ```java class Person { private String name; @...

    java判断Long类型的方法和实例代码

    Java判断Long类型的方法和实例代码 Java是一种流行的编程语言,广泛应用于安卓开发、Web开发、企业软件开发等领域。在Java编程中,我们经常需要判断变量的类型,特别是判断Long类型,因为Long类型是Java中的一种...

    Java string不可变原理实例解析

    7. **API设计**:String类提供了许多方法,如substring()、concat()等,这些方法返回新的String对象而不是修改原始对象。如果String是可变的,那么这些方法的行为会更加复杂,需要考虑是否应修改原对象还是返回新...

    精品专题(2021-2022年收藏)Java基础英语单词表.docx

    32. **method**:方法是包含特定操作的代码块,可由类的实例调用。 33. **version**:软件的版本标识符,用于区分不同版本的代码。 34. **parameter**:方法参数用于传递值给方法。 35. **array**:数组是相同...

    Java基础英语单词表.pdf

    3. **main** - Java应用程序的入口点,`main`方法是程序执行的起点。 4. **class** - 定义对象的蓝图,是Java中的核心概念,用于创建对象。 5. **system** - 通常与`System.out.println()`一起使用,用于在控制台...

    (word完整版)Java基础英语单词表.doc

    3. **main** - 一个程序的入口点,通常在Java应用中是`public static void main(String[] args)`方法。 4. **class** - 用来定义对象的蓝图或模板,是面向对象编程的基础。 5. **system** - 在Java中,常与`System....

    (完整版)Java基础英语单词表.doc

    9. **string** - 字符串:`String`是Java中用来处理文本的类。 10. **double** - 双精度浮点数:用于存储精确的数值,比单精度浮点数(float)更精确。 11. **character** - 字符:`char`类型用于存储单个字符。 ...

    HttpClient应用实例2

    String charset = contentType.substring(contentType.indexOf("charset=") + 8).trim(); } else { // 如果服务器没有提供charset,可以默认为UTF-8 String charset = "UTF-8"; } InputStream is = entity....

    StringUtils(最新)

    `StringUtils` 是 Apache Commons Lang 库中的一个核心类,提供了大量关于字符串操作的实用方法,旨在作为 Java 核心库的扩展。这个库在 `commons-lang-2.5` 版本中是最新的,尽管现在可能有更新的版本,但这个版本...

    测试职位笔试题_参考答案.doc

    1. 一条软件缺陷(或者叫 BUG)记录都包含了编号、BU 所属模块、BUG 描述、BUG 级别、发现日期、发现人、修改日期、修改人、修改方法、回归结果等等。要提交高质量的软件缺陷记录,需要参加需求以及详细的设计等前期...

    java代码-05 谭梓豪4

    8. **字符串处理**:String类的方法,如concat、substring、indexOf、replace等。 9. **数组**:一维和多维数组的声明、初始化、遍历及操作。 其次,`README.txt`文件通常包含了项目的相关信息,例如: 1. **项目...

    android 安装广播

    packageName = packageName.substring(8); } // 使用PackageManager获取应用信息 PackageManager pm = context.getPackageManager(); try { ApplicationInfo appInfo = pm.getApplicationInfo(packageName, ...

    U5__Examen

    6. **字符串处理**:String类的方法,如concat、substring、indexOf、replace等。 7. **函数式编程**:Java 8引入的Lambda表达式和Stream API,用于简化处理集合数据的方式。 8. **多线程**:了解线程的创建...

    CodingBat-JAVA

    4. **字符串处理**:字符串的拼接、查找、替换、分割等操作,以及String类的方法,如indexOf()、substring()、trim()、length()等。 5. **函数与方法**:自定义函数的编写,参数传递,返回值,递归,以及重载和重写...

Global site tag (gtag.js) - Google Analytics