集合

时间:2017-11-03 01:53:19

标签: java

这是我的要求。它抛出内存不足和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;
  }

2 个答案:

答案 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);
}