垃圾收集静态函数内的局部变量

时间:2015-01-27 18:06:41

标签: java memory-leaks garbage-collection

我在Java下面编写了ETL函数,每分钟调用1000-2000个事件,并返回已成功加载的事件(用于某些检查指向):

public static Event[] loadEvents(Event[] events) {
    List<ITuple> persistedEvents = new ArrayList<Event>();
    List<DestinationMessage> destinationMessages = convertToDestinationFormat(events);
    loader.send(destinationMessages); // Synchronous persistence call
    for (Event event : events) {
        persistedEvents.add(event);
    }
    return persistedEvents.toArray(new Event[persistedEvents.size()]);
}

private static List<DestinationMessage> convertTuplesToKafkaMessages(Event[] events) {
        List<DestinationMessage> destinationMessages = new ArrayList<DestinationMessage>();
        for (Event event : events) {
            DestinationMessage destinationMessage = new DestinationMessage();
            destinationMessage.setData(event.getData());
            destinationMessages.add(destinationMessage);
        }
    return destinationMessages;
}

如果非静态函数我确定没有内存泄漏,但我想了解它是否有任何区别,如果函数是静态的,如上所述?

我认为不应该在函数调用中实例化对象,因此每次函数调用结束时它们都应该收集垃圾(并且取决于垃圾收集器实际执行的时间)。

我在我的机器上面临堆空间问题,只是想知道这个功能是否可能是罪魁祸首。内存使用率从6GB增加到16GB(可用内存)。

有人可以指出内存泄漏,如果有的话。我是否需要在destinationMessages结束时将NULL设置为loadEvents

2 个答案:

答案 0 :(得分:1)

静态字段与类关联,而不是单个实例。

在卸载类的ClassLoader时清除静态字段。在许多简单的程序中,这绝不是。

如果您希望将字段与实例关联并清理,则清除实例,将其设为实例字段,而不是静态字段。

答案 1 :(得分:0)

您在垃圾收集方面没有正确的事实

在Java(或C或C ++)中有功能3种内存:系统mem(忽略),堆栈和堆。函数返回时,堆栈存储器自动清除。需要收集的唯一内存是在堆中分配的内存,这只有在垃圾收集(gc)运行时才会发生。

这与静态/非静态上下文无关。

如果您遇到内存问题,您可能需要创建一个计数器来计算调用方法的次数,并在一定次数的运行后显式调用System.gc();