繁体   English   中英

如何在Java中管理大型缓冲区? 超出了GC开销限制

[英]How to manage a large buffer in java? GC overhead limit exceeded

我尝试使用SAXParser解析2GB的XML文件。 我的任务是关于信息检索,并被告知处理内存中所需的信息。 该文件分为单词组成的文档。 每个单词都是一个对象,应该在其他文档中存储其外观。

当下一个文档开始时,我弹出所有这些对象,然后将它们放入一个大小合适的数组中,以尽可能提高内存效率。 现在的问题:该方法创建了太多的临时对象,因此垃圾收集器完成了太多的工作。 有没有办法避免创建那么多临时对象或使缓冲区不与GC冲突?

public class Stack<T> {
StackObject<T>  top;
boolean empty;
int entryCounter;
Stack(){
    empty = false;
}   
public void init(T obj){
    top = new StackObject<T>(obj);
}
public T pop(){ 
    T tmp = top.self;
    if(top.next != null){
        top.self = null;
        top = top.next;
    }
    else{
        empty = true;
    }
    return tmp;
}
public void push(T obj){
    StackObject<T> tmp = new StackObject<T>(obj);
    tmp.next = top;
    top = tmp;
    entryCounter += 1;
    if(tmp.next == tmp){
        System.out.println("ERROR");
    }
}
}

class StackObject<T>{
T self = null;
StackObject<T> next = null;
StackObject(T obj){
    self = obj;
}
}

您的Stack类在使用内存方面效率低下。 每个堆栈条目使用的内存大约是ArrayList 4倍。

你这样说:

例如,由于调整大小需要太多时间,因此使用Arraylist太慢了。

解决该问题的一种方法是实现基于数组的堆栈,该堆栈在调整大小时将支持数组的大小加倍。 如果使用此策略调整大小,则由于调整大小, N被推入空堆栈的副本将提供N2N额外的副本。

无论如何,尽管您可能节省了调整大小的CPU的负担,但另一方面是,当前的实现在构建许多StackObject实例的开销中损失了很多收益,并且间接产生了垃圾回收成本,局部性差和内存增加脚印。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM