【发布时间】:2015-03-26 11:00:59
【问题描述】:
我在 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吗?
【问题讨论】:
-
你不知道你创建的对象什么时候被GC收集的;它自己运行,当它认为它应该运行时
-
eclipse MAT 是查找内存泄漏的好工具eclipse.org/mat
-
@Vince Emigh 这部分正确。如果您使用
Runtime's功能跟踪内存大小,您肯定可以见证垃圾收集的结果。但当然,这并不一定意味着符合垃圾回收条件的特定对象实际上已被释放。 -
据我所知,幻影引用可能有助于检查对象是否被垃圾回收。
-
没错,我对此没有任何意见。但我唯一担心的是我的代码中是否存在任何内存泄漏。垃圾收集器会表现得如此糟糕,以至于在我在 8 小时内失去 10GB 的 RAM(6 到 16GB)之前不进行垃圾收集吗?
标签: java memory-leaks garbage-collection