我用 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
(可用内存)。
有人可以指出内存泄漏(如果有)吗?我需要在 loadEvents
末尾将 destinationMessages
设置为 NULL
吗?
最佳答案
静态字段与类关联,而不是与单个实例关联。
当保存类的类加载器卸载时,静态字段将被清除。在许多简单的程序中,这永远不会。
如果您希望字段与实例关联并清理,那么实例就会被清理,请将它们设置为实例字段,而不是静态字段。
关于java - 静态函数内局部变量的垃圾收集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28177108/