- 浏览: 75472 次
- 性别:
- 来自: 厦门
文章分类
最新评论
-
覃永波:
引用[*][img][/img][url][/url]
java 读取txt,java读取大文件 -
bits00:
...
tcpdump网摘
此问题在项目中被发现,经查看JDK源码(JDK1.6),String类的public String substring(int beginIndex, int endIndex)的实现让我很意外。
想重现这个场景很容易,请看代码。
package TestStringOutOfMemory; import java.util.ArrayList; import java.util.List; public class LeakTest { public static void main(String...args) { List<String> handler = new ArrayList<String>(); for(int i = 0; i < 100000; i++) { Huge h = new Huge(); handler.add(h.getSubString(1, 5)); } } } class Huge { private String str = new String(new char[100000]); public String getSubString(int begin, int end) { return new String(str.substring(begin, end)); } }
执行此代码结果:
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
问题就出在Huge类的 getSubString 方法,它调用了String类的substring方法。
来让我们看看 substring 类的实现吧,JDK源码如下:
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); }
再让我们接下来看看 new String(offset + beginIndex, endIndex - beginIndex, value); 的实现:
// Package private constructor which shares value array for speed. String(int offset, int count, char value[]) { this.value = value; this.offset = offset; this.count = count; }
char[] value 数组被共享了。
在我们的main函数里的循环中,每循环一次后,我们希望Huge对象被回收,且释放它占有的内存。
但实际上 private String str = new String(new char[100000]); 占有的内存并不会被释放。
因为 我们通过 Huge 类的 getSubString 方法得到的 String 对象还存在(存在于handler的列表中),
它虽然是 length 只有 4 的对象,却享有着 char[100000] 的空间。
解决方案:
可以修改Huge 类的 getSubString 方法如下:
public String getSubString(int begin, int end) { return new String(str.substring(begin, end)); }
只要再套一个String的构造方法即可。
至于为什么,看看JDK源码,一看便知了。这里就不贴出来了。
发表评论
-
飞鸽收藏(转)
2012-04-27 18:18 1367我们常在局域网内用飞鸽进行沟通、文件传输。有天突发奇想,要是我 ... -
主题:边读边写【7】 ----java 多线程实战【Thread /Executors】(转)
2012-04-23 11:39 1389http://www.iteye.com/topic/1122 ... -
牢骚一下,JavaFx 2.0太坑人了
2012-04-18 20:45 17用了半周看了下JavaFx2.0 ,看官方例子感觉还不 ... -
Java中一些关于日期、日期格式、日期的解析和日期的计算 (转)
2012-04-12 11:00 0http://www.blogjava.net/Jkallen ... -
操作property文件(转)
2012-04-12 10:51 966对于一些常量我们经 ... -
Java 系统运行时性能和可用性监控
2012-04-12 10:40 1182简介: 当今的许 ... -
Jconsole_一个监控JVM资源的JDK自带小工具 (转)
2012-04-12 10:32 1223最近一直忙着测一个tomcat的接口,测试中LR总出现2779 ... -
探索JVM运行状态的利器—JVMPI,HPROF_剑_百度空间 (引)
2012-04-12 10:29 1388.什么是JVMPI?Java Virtual ... -
JVM jvmpi (转)
2012-04-12 10:18 1572转自 http://chain.blog.163.com/bl ... -
java 格式化小数
2012-03-09 16:53 1522DecimalFormat 是 NumberForm ... -
org.apache.commons.net.ftp.FTPClient 例子(转)
2012-03-02 09:26 1464转自 http://zhangnet1.iteye.com/b ... -
java查询一次性查询几十万,几百万数据解决办法(转)
2012-02-29 09:15 1004java查询一次性查询几十万,几百万数据解决办法 很早 ... -
java 读取txt,java读取大文件
2012-02-26 19:39 2117java 读取txt,java读取大文件 设置缓存大小 ... -
StringUtils用法+StringUtils详细介绍
2012-02-26 19:38 936StringUtils用法+StringUtils详细介绍博文 ... -
java 字节流网址收藏(暂)
2012-02-07 10:43 750Java I/O关于缓冲区部分提高性能的源码分 ... -
Swing 线程之SwingUtilities.invokeLater()(转)
2012-01-06 10:00 1225声明:本文章转自 http://blog.csdn.ne ... -
Swing 线程之SwingUtilities.invokeLater() (转)
2012-01-06 09:59 2声明:本文章转自 http://blog.csdn.net/b ... -
Java Swing GUI多线程之SwingUtilities.invokeLater和invokeAndWait
2012-01-05 16:55 5439在Java中Swing是线程不安全的,是单线程的设计, ... -
用java.util.Timer定时执行任务
2012-01-05 16:11 844如 ... -
ubuntu java配置
2011-12-30 20:54 1083Ubuntu10.10安装sun-Java6-jdk ...
相关推荐
Java 中的 substring 方法是一个非常常用的字符串操作方法,但是在 JDK 1.6 中,如果不当使用该方法,可能会导致严重的内存泄漏问题。下面我们将详细介绍 Java 中由 substring 方法引发的内存泄漏问题的原因和解决...
在 JDK 6 中,使用 substring 方法可能会出现的问题是,如果你只需要使用很短的一段字符串,但是你实际上引用了整个字符串,这个很长的字符串无法被回收,造成了存储空间的浪费,甚至可能造成内存泄漏。这是一个已知...
但是,如果String与其他对象组合形成引用链,可能会导致内存泄漏,这时需要注意及时解除引用,以便垃圾回收器能正确工作。 总之,Java中的String类是一个功能强大且基础的类,理解其特性和使用技巧对于提升编程效率...
综上,Java中的String类提供了丰富的方法来处理字符串,但正确使用这些方法需要对Java内存模型、不可变对象和多线程安全等方面有深刻理解。这十个问题和解决方法,可以帮助开发者高效且正确地在Java中进行字符串操作...
在1.6中,这个方法可能导致内存泄漏,因为它会将字符串添加到永久代(PermGen)中,这在处理大量动态字符串时可能会导致问题。 ### JDK 1.7中的String JDK 1.7对`String`类进行了一些性能优化,特别是在`...
总结来说,`String.substring`在不同的JDK版本中有不同的实现,从JDK 1.6到1.7的改进主要是为了防止因共享字符数组导致的内存泄漏。在编写涉及大量字符串操作的代码时,理解这些细节可以帮助我们更好地控制内存使用...
- **熟悉String的使用**: 如何正确使用`String`类的各种方法,如`equals()`、`indexOf()`、`substring()`等。 - **熟悉Java关键字**: 了解Java语言的关键字及其用途,如`final`、`static`、`abstract`等。 - **集合...
在Java编程语言中,String是一个非常重要的类,它被广泛用于表示和处理字符串数据。在面试中,关于String类的问题往往是必考题。以下是一些在面试中可能会遇到的问题,以及对应的解释和知识点汇总。 1. 在比较两个...
4. **内存泄漏:** 在Java中,长时间持有不再使用的对象引用可能导致内存泄漏。应当及时释放不再使用的资源,比如关闭数据库连接、文件句柄等。 5. **性能优化:** 对于性能敏感的应用,应当关注算法的选择和数据...
9. **内存管理**:由于每次修改都会创建新对象,过多的`String`操作可能导致内存泄漏。因此,在处理大量字符串操作时,需要注意性能优化。 10. **垃圾回收**:不可变性也有助于垃圾回收,因为当一个`String`对象...
例如,在JDK6中,String的substring()方法在创建新字符串时,没有正确地解除对原字符串部分字符的引用,导致了内存泄漏。这个问题在JDK7中得到了修复。 防止内存泄漏的一些策略包括: 1. 适时清理集合类,避免使用...
面对内存泄漏问题,Java通过垃圾收集机制自动回收不再使用的对象,但过度复杂的引用结构可能导致内存无法释放,形成内存泄漏。 总之,Java面试中会涉及语言基础、面向对象特性、JVM、类加载、数据类型转换、排序...
### Java面试测试题目知识点...- Java中使用静态变量来模拟全局变量的行为,避免全局变量可能导致的问题。 #### 57. 如何将String类型转化成Number类型 - 使用`Integer.parseInt()`、`Double.parseDouble()`等方法。
本文总结了关于Java中String类最常见的十个问题,涉及字符串比较、敏感信息安全、switch语句中的使用、字符串与数字之间的转换、字符串拆分、字符串截取、可变字符串与不可变字符串的区别、字符串重复拼接、字符串...
- **String类的常用成员方法** - 构造方法:如 `String(byte[] bytes, int offset, int length)` 用于从字节数组中构造字符串。 - `equalsIgnoreCase`: 忽略大小写的字符串比较。 - `indexOf`: 查找字符或子字符...
String类在Java中是不可变的,它的常用方法如concat()、substring()、indexOf()等是SCJP考试的常见考点。同时,了解StringBuilder和StringBuffer线程安全的字符串操作也是必要的。 六、IO流与NIO 输入/输出流(IO流...
Java 中会存在内存泄漏吗,请简单描述。Java 中实现多态的机制是什么?垃圾回收器的基本原理是什么?垃圾回收器可以马上回收内存吗?有什么办法主动通知虚拟机进行垃圾回收?等问题可以根据 Java 的语法和语义来回答...
4. **字符串操作**:Java中的`String`类有许多方法,如`concat()`, `substring()`, `trim()`等,理解它们的用法和行为差异是必要的。 5. **数组与集合**:Java中的数组和集合(如ArrayList, HashSet, HashMap等)的...