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

String.substring(int beginIndex, int endIndex)方法来截取字串,但是该方法为了节约时间,提升性能,浪费了大量空间,其源代码如下

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

String(int offset, int count, char value[]) {
    this.value = value;
    this.offset = offset;
    this.count = count;
    }  

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

public class SubStringTest {  

    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处理。

//JDK 7
public String(char value[], int offset, int count) {
    //check boundary
    this.value = Arrays.copyOfRange(value, offset, offset + count);
}  

public String substring(int beginIndex, int endIndex) {
    //check boundary
    int subLen = endIndex - beginIndex;
   return new String(value, beginIndex, subLen);  
String x = "abcdef";
x = x.substring(1,3);
时间: 2024-11-02 14:18:36

java-subString方法易导致内存溢出的相关文章

Java中由substring方法引发的内存泄漏

在Java中我们无须关心内存的释放,JVM提供了内存管理机制,有垃圾回收器帮助回收不需要的对象.但实际中一些不当的使用仍然会导致一系列的内存问题,常见的就是内存泄漏和内存溢出 内存溢出(out of memory ) :通俗的说就是内存不够用了,比如在一个无限循环中不断创建一个大的对象,很快就会引发内存溢出. 内存泄漏(leak of memory) :是指为一个对象分配内存之后,在对象已经不在使用时未及时的释放,导致一直占据内存单元,使实际可用内存减少,就好像内存泄漏了一样. 由substri

WPF循环加载图片导致内存溢出如何解决

程序场景:一系列的图片,从第一张到最后一张依次加载图片,形成"动画". 生成BitmapImage的方法有多种: 1.var source=new BitmapImage(new Uri("图片路径",UriKind.xxx)); 一般的场景使用这种方法还是比较方便快捷,但是对于本场景,内存恐怕得爆.2. var data =File.ReadAllBytes("图片路径"); var ms = new System.IO.MemoryStrea

压缩-android展示多张大图导致内存溢出问题

问题描述 android展示多张大图导致内存溢出问题 现在在开发一个联系人头像展示功能,每一屏页面大概展示72张图片,已做了异步加载,但是由于图片太大了,依然会导致内存溢出,请问有没有什么好的不会导致图片变模糊并且执行效率比较高的压缩方法,或者请问有没有其他好的解决方法? 解决方案 Android 内存溢出问题android从Uri得到Bitmap内存溢出问题Android使用bitmap导致内存溢出(oom)问题 解决方案二: 你的图片是头像,那么肯定显示的比较小,你在网络读取图片的时候,执行

不停的用simpleadapter加载更新gridview导致内存溢出,怎么解决

问题描述 不停的用simpleadapter加载更新gridview导致内存溢出,怎么解决 public class Myragment extends Fragment { private GridView grid; ArrayList> arraylist = null; int[] temp = new int[] {R.id.cell}; String[] temp1 = new String[] { "cell" }; MyHandler handler = new

viewpager加载多张大图导致内存溢出

问题描述 viewpager加载多张大图导致内存溢出 同样的app程序,在原生Android系统上就不出现内存溢出,在华为系统上就会出现内存溢出的情况, viewpager 加载多个布局,每个布局里面都有一张大图,实现了类似于图片游览器的功能. 里面有写回收图片操作和压缩为原图一半的操作

kettle java 内存溢出-java调用kettle导入数据内存溢出!!!!!

问题描述 java调用kettle导入数据内存溢出!!!!! 现在用java调用kettle的ktr模板往数据库中导入数据.kettle版本为4.2.0,oracle版本为11g. 无论jvm设置多大,只要文件数量比较多,内存会一直涨到溢出.调用过程就创建多个ktr对象TranMete,然后放在Trans里面运行. 求大神解决问题. 解决方案 提交数量改小点试试?

Java多线程 导致内存溢出问题 直接上代码

问题描述 packagetg.execute;importjava.awt.image.BufferedImage;importjava.io.BufferedReader;importjava.io.IOException;importjava.io.InputStream;importjava.io.InputStreamReader;importjava.io.UnsupportedEncodingException;importjava.util.Date;importjava.util

Android 异步获取网络图片并处理导致内存溢出问题解决方法

测试环境为Adnroid 2.1以上. 1.AndroidManifest.xml 权限配置: 添加互联网访问权限: 复制代码 代码如下: <uses-permission android:name="android.permission.INTERNET" /> 2.异步图片类 ImageDownloadTask 复制代码 代码如下: import java.io.ByteArrayOutputStream; import java.io.IOException; imp

java常见的几种内存溢出和解决方案

项目组最近在开发中经常会出现一些意想不到的内存溢出问题.下面我就说说我们常见的几种内存溢出吧!1.JVM Heap(堆)溢出:java.lang.OutOfMemoryError: Java heap spaceJVM在启动的时候会自动设置JVM Heap的值, 可以利用JVM提供的-Xmn -Xms -Xmx等选项可进行设置.Heap的大小是Young Generation 和Tenured Generaion 之和.在JVM中如果98%的时间是用于GC,且可用的Heap size 不足2%的