我在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
?
答案 0 :(得分:1)
静态字段与类关联,而不是单个实例。
在卸载类的ClassLoader时清除静态字段。在许多简单的程序中,这绝不是。
如果您希望将字段与实例关联并清理,则清除实例,将其设为实例字段,而不是静态字段。
答案 1 :(得分:0)
您在垃圾收集方面没有正确的事实
在Java(或C或C ++)中有功能3种内存:系统mem(忽略),堆栈和堆。函数返回时,堆栈存储器自动清除。需要收集的唯一内存是在堆中分配的内存,这只有在垃圾收集(gc)运行时才会发生。
这与静态/非静态上下文无关。
如果您遇到内存问题,您可能需要创建一个计数器来计算调用方法的次数,并在一定次数的运行后显式调用System.gc();