如何在java中管理大缓冲区? GC开销限制超过

时间:2016-08-14 10:15:45

标签: java xml garbage-collection buffer

我尝试使用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;
}
}

1 个答案:

答案 0 :(得分:0)

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

你这样说:

  

例如,使用Arraylist变得太慢,因为调整大小需要花费太多时间。

解决这个问题的一种方法是实现一个基于数组的堆栈,它在调整大小时将后端数组的大小加倍。如果您使用此策略进行大小调整,则由于调整大小,N推送到空堆栈将在N2N个额外副本之间提供。

无论如何,虽然你可能在调整大小时节省了CPU,但另一方面是你当前的实现在构造许多StackObject实例的开销和垃圾收集的间接成本中损失了很多。 ,地点不佳,内存占用增加。