you must have some recursion and that consumed all the stack space. gc can't help at all.

解决方案 »

  1.   

    no. you can't manually clear it.
    you must be having some inproper recursion. Find it and correct it.
      

  2.   

    是这样,我要对一个上百找的文件进行操作,肯定不能一下子读进来,所以就每次读300000个字符到一个String类的对象里,然后每次操作后再读取下一段300000字符,如此循环。
    while(没读到文件尾)
    {
       in.read(data,0,300000)
       sqfile = new String(data,0,300000);    line 369 
    }
    可一般运行到第85次,就会在line 369出现no stack错误。这是怎么回事,我根本没有用到递归呀!
      

  3.   

    尽量用StringBuffer对象,
    少用String对象,
    你的问题就可以解决
      

  4.   

    StringBuffer对象我也用过,表面上看append函数可以避免每次new String开辟新的空间,但我跟踪过append函数也是要new的。
      

  5.   

    我个人认为String对象有一些小BUG,
    而且对同一个String对象进行多次连接或者剔除操作后,
    会出现溢出错误,
    用StringBuffer能避免这个错误
      

  6.   

    我确实跟踪过,连StringBuffer的delete函数都会new String的。
      

  7.   

    void openFile(String fileName)
      {
        int i,temp,member,chars_read = 0;
        int first = 0,last = 300000;
        String sqfile;
        int n = 0;
        in = new RandomAccessFile(fileName,"r");
          int size = (int)in.length();
          byte[] data = new byte[300000];
          while(true)
          {
            in.seek((long)first);
            int len = 300000;
            if(last < size)
            {
              in.read(data,0,300000);
            }
            else
            {
              in.read(data,0,size - first);
              len = size - first;
            }
            sqfile = new String(data,0,len);//出错行
            temp = getGenIndex(data,len,n);//处理函数
            if(temp == -1)
              break;
            first += temp;
            pos[n] = first;
            n ++;
            last = first + 300000;
            sqfile = null;
            System.gc();
            }
     }
      

  8.   

    void openFile(String fileName)
      {
        int i,temp,member,chars_read = 0;
        int first = 0,last = 300000;
        String sqfile;
        int n = 0;
        in = new RandomAccessFile(fileName,"r");
          int size = (int)in.length();
          byte[] data = new byte[300000];
          while(true)
          {
            in.seek((long)first);
            int len = 300000;
            if(last < size)
            {
              in.read(data,0,300000);
            }
            else
            {
              in.read(data,0,size - first);
              len = size - first;
            }
            sqfile = new String(data,0,len);//出错行
            temp = getGenIndex(data,len,n);//处理函数
            if(temp == -1)
              break;
            first += temp;
            pos[n] = first;
            n ++;
            last = first + 300000;
            sqfile = null;
            System.gc();
            }
     }我是在jbuilder5下运行的。
      

  9.   

    are you using the sqfile? seems you are creating and discarding the string without using it.
      

  10.   

    笔误,
    temp = getGenIndex(sqfile,len,n);//处理函数
      

  11.   

    what is in getGenIndex? is it possible that the sqfile gets leaked there?
      

  12.   

    sqfile = new String(data,0,len);//出错行
    temp = getGenIndex(data,len,n);//处理函数
    改为:
    {
       
       String sqfile = new String(data,0,len);//出错行
       temp = getGenIndex(data,len,n);//处理函数
       sqfile = null;
    }
      

  13.   

    sqfile = null;提前几句话有用吗?
      

  14.   

    I'm saying that you may leak the sqfile to the getGenIndex.
    I can't see anything wrong with this function, that's why I'm wondering what's in the getGenIndex.
      

  15.   

    最好把getGenIndex也拿出来看看,还有出的错误。另外是只有大文件时才出错吗?
      

  16.   

    int getGenIndex(String sqfile,int length,int num)
      {
        int startpoint = 0,temp,i,titlebegin,titleend,seqbegin,seqend;
        char seqch;
        String tmpsq = "";
        choices.addElement(new String());
        temp = sqfile.IndexOf("ACCESSION",startpoint,length);
        if(temp !=  -1)
        {
          startpoint = sqfile.IndexOf(" ",temp,length);
          while(sqfile.charAt(startpoint) == ' ')
            startpoint ++;
          titlebegin = titleend = startpoint;
          while(sqfile.charAt(titleend) != ' '&&sqfile.charAt(titleend) != '\n')
            titleend ++;
          tmpsq = sqfile.substring(titlebegin,titleend);
          choices.setElementAt(tmpsq,num);
          choices.trimToSize();
          return titleend;
        }
        else
          return -1;
      }确实是处理大文件时出现错误。
      

  17.   

    try to change the following:
    tmpsq = sqfile.substring(titlebegin,titleend);
    as
    tmpsq = new StringBuffer().append(sqfile.substring(titlebegin,titleend)).toString();see if it works.
      

  18.   

    老兄,sqfile.IndexOf这个方法编译不过去的,indexOf只能用一个或两个参数。
      

  19.   

    to ajoo(jet pig) : it really works,but can u tell me why it works,
    by the way , r u abroad?
      

  20.   

    原来是这样,Sun的String类真够变态的。这是因为你调b = a.substring(...)时b是一个新的String实例,但b和a底下共享着同一个char数组用于存储字符串数据。这时如果b不被垃圾收集,a也不会被垃圾收集。由于你把b放在choices中保存了,所以a和b都不会被垃圾收集,造成sqfile这个大字符串在getGenIndex调用后仍然存在。StringBuffer对数组做了拷贝,所以就没有问题了。
    这真是一个严重的问题,建议加入精华区。想来Sun的实现是因为字符串是不可改变的,所以共享一个数组也不会有冲突的问题,但在垃圾收集上成问题了。
      

  21.   

    哦,上面说的有点问题。不是a不会被垃圾收集,而是a和b共享的那个数组不会被垃圾收集。关于速度,你可以用System.currentTimeMillis测一下瓶颈在那里。如果你仅是单向检索文件,用流可能快些。
      

  22.   

    sigh. no silver bullet. I believe the sharing of immutable String really helps in most cases. If I write the jdk, I would be doing the same thing. It'll be really hard for the gc to collect part of an array though.I won't blame Java for this.By the way, I wouldn't implement getGenIndex that way. You are creating a big String based on an array. why not just use that array to do the search? should be faster.Yes, I'm abroad now, that's why I cannot input Chinese most of the time.
      

  23.   

    i had tried to do the operation on the array,but it was also terribly slow.I thought string would be faster using it's own function.ps, i will apply for graduate studies in usa, so i wanna b friends with me ,can i write to u ,u can see my email address in your short messege
      

  24.   

    to : jimjxr(宝宝猫) 
    请问如何在jbuilder里用System.currentTimeMillis测瓶颈,
    我编得是这样一个基因序列分析平台,第一步先从源文件中读取基因序列的目录并生成索引表(因为一个文件里有许多基因序列,每条序列有一个名字,现在我把序列名的列表显示出来),然后鼠标点击某一个序列名后,我再根据索引表回到文件中读取这一条完整序列,然后对其进行某些计算操作,你说的流指得是什么?
      

  25.   

    ajoo: I agree, I overacted, sorry. It's just Java is supposed to avoid memory leaks, not introduce more subtle leaks. The doc on the contract of substring is misleading, or at least not very clear. If you don't know the implementation, you're very likely to make the mistake, which is not acceptable.
      

  26.   

    oscarjiao() :流是指用Reader,不过既然你要再回到文件中读取序列就不能用流了,用RandomAccessFile是对的。String下面也是一个数组,所以不会比数组更快,只不过你不用自己写搜索的函数罢了。实际上这样会更慢,因为new String时要拷贝数组。另外你最好看看IO方面文章,还有data不必取那么大,一般几K最好。
    用System.currentTimeMillis是指你可以测一下调用方法的时间,这样能知道时间都费在那了。如
    long t = System.currentTimeMillis();
    ... //运行方法
    t = System.currentTimeMillis() - t;
    System.out.println( "t=" + t ); //打印所用时间