zl程序教程

您现在的位置是:首页 >  后端

当前栏目

java-subString方法易导致内存溢出

JAVA内存方法 导致 溢出 substring
2023-09-27 14:26:36 时间

String.substring(int beginIndex, int 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)返回了一个新建的String对象,查看该构造函数源码如下:


其只是通过偏移量来获取一个字符数组的子数组,但是原数组中,没有被选择的并没有及时释放,因此,如果原字符串很长,而需要的子字符串又很短,则很容易造成内存溢出,如以下代码:


public static void main(String[] args) { List String handlerList = new ArrayList String * HugeStr不到100000次就内存溢出 但是ImprovedHuge不会 for (int i = 0; i 100000; i++) { HugeStr h = new HugeStr(); handlerList.add(h.getSubString(1, 5)); System.out.println("times:"+i); static class HugeStr { private String str = new String(new char[100000]); // 一个很长的字符串 public String getSubString(int begin, int end) { // 获取字符串,有溢出 return str.substring(begin, end); }

解决方案x = new String(x.substring(x, y));这样的话,就会创建一个新数组,切断与原来的数组的引用,既然JDK6中存在这样一个鸡肋,SUN工程师们肯定会解决的,在JDK7中,该鸡肋已经得到解决。在JDK7中调用substring时,会自动创建一个字符数组,新字符串指向新字符数组,则原来数组可以被GC处理。


int subLen = endIndex - beginIndex; return new String(value, beginIndex, subLen);
Java String 的 常量池 和 intern 方法 简析 Java String 的 常量池 和 intern 方法 简析字符串常量池和 intern 方法 先举个例子,我们创建 10000 个相同的 String,并且不使用常量池 String[] list = new String[10000]; for (int i = 0; i 10000; i++) { list[i] = new String(new char[]{ a , b , c 结果是:每个 String 都用新开的对象,占用大量内存
现在我们这样创建,增加一个 map ,key 和 value 内容一样,每次取的时候,先检查一下 map 里面有没
java之intern()详细分析(全) 目录前言1. 源码2. 实战代码 经常在面试或者是一些习题上偶尔看到这个函数 却有些懵懵懂懂 今天就通过源代码彻底解析一下 这个代码的主要功能是 返回字符串对象的规范化表示形式 1. 源码 通过查询其源码 翻译过来的主要意思是 返回字符串对象的规范表示。 最初为空的字符串池由String类私有维护。 当调用intern方法时,如果池中已经包含一个与equals(0bject)方法确定的string对象相等的字符串,则返回池中的字符串。 否则,将此String对象添加到池中并返回对该String对象的
java中charAt()方法的使用 此方法返回这个字符串的指定索引处的char值。第一个char值的索引为0. IndexOutOfBoundsException -- 如果index参数为负或不小于该字符串的长度.
记录一次Java递归调用导致java.lang.StackOverflowError错误 通过递归调用每次查询500条数据的id,再通过id删除记录的方式,数据量一大,导致递归过深,栈帧数超出虚拟栈深度,虚拟机栈过多,报java.lang.StackOverflowError错误。
Java从入门到精通六(java中的字符串变量String,StringBuilder,StringBuffer) 一: String 1:String的数据类型 首先我们认识到java中的数据类型分为基本数据类型和引用数据类型。基本数据类型分为数值,字符,布尔,而引用数据类型分为类,接口,数组。 String是属于引用数据类型的。因为String本身就是一个类 需要了解基本数据类型和引用数据类型的区别。基本数据类型是直接存储在内存的栈上的,引用数据类型继承自Object类,按照对象的内存模式进行存储。我们的引用存放在内存的栈上,而对于对象本身的值存放在内存的堆上。我们java中通过new出来的对象就会存放在堆中。