这是我的要求。它抛出内存不足和GC开销限制超出异常。请建议实施此方法的最佳方法。
public static List<Consumer> retrieve(){
List<Consumer> consumers = new ArrayList();
for (int i = 0; i < 10000; i++)
{
Consumer consumer = new Consumer();
consumer.setAge(new Integer(i));
consumer.setBirthDate(new SimpleDateFormat("ddMMyyyy").parse("01061986"));
consumer.setName("Consumer" + new String(new Integer(i).toString()));
consumers.add(consumer);
}
return consumers;
}
答案 0 :(得分:1)
更新:嗨曼努埃尔,我已经重读了你的问题。我们需要有关您的问题的更多信息。你在创建的Consumer实例中做了什么?您必须确保快速删除对它们的任何引用,以便GC可以摆脱它们。不过,不知道1秒是否足够。
请添加更多信息。如果您发现它有用,我会留下我之前的答案。 : - )
从您发布的代码中,我可以告诉您它使用50MB堆大小在我的计算机上成功运行。如果您的计算机上50MB还不够,我确定您有更多代码。
您可以开始对给定的函数执行一些优化。我将首先删除一些实例化和铸件。看看以下第一种方法:
public static Consumer[] retrieve() throws ParseException{
final SimpleDateFormat sdf = new SimpleDateFormat("ddMMyyyy");
final int MAX = 100000;
final Consumer[] consumers = new Consumer[MAX];
for (int i = 0; i < MAX; i++) {
Consumer consumer = new Consumer();
consumer.setAge(i);
consumer.setBirthDate(sdf.parse("01061986"));
consumer.setName("Consumer" + i);
consumers[i] = consumer;
}
return consumers;
}
对其余代码的一些更改必须考虑到:
int
,它是一个原语,而不是Integer
这是一个类。List
使用您提供以下内存信息的代码:
Free memory before (bytes): 50331648
Free memory after (bytes): 24865408
随着代码更改,我将其更改为:
Free memory before (bytes): 50331648
Free memory after (bytes): 33736624
您可以看到内存消耗的重大变化。
如果您对如何检查JVM中的可用内存感兴趣,请查看:Runtime.getRuntime().freeMemory()
。
最后,我必须说,添加更多信息以帮助您获得更好的答案非常重要。
答案 1 :(得分:0)
您可以使用Stream<Consumer>
或Iterator<Consumer>
作为返回类型,也可以修改调用此方法的其他部分来执行此操作。无法返回List<Consumer>
,它将包含仅有50MB的所有100,000个对象实例。
将您的示例方法转换为Stream<Consumer>
版本:
public static Stream<Consumer> retrieve() {
return Stream.iterate(
new Consumer(0),
lastConsumer -> new Consumer(lastConsumer.getAge() + 1)
.limit(100000);
}
并更改您的Consumer构造函数以初始化所有变量。
public Consumer(int age)
{
this.setAge(age);
consumer.setBirthDate(new SimpleDateFormat("ddMMyyyy").parse("01061986"));
consumer.setName("Consumer" + age);
}