异常java.lang.OutOfMemoryError:树映射超出了GC开销限制

异常java.lang.OutOfMemoryError:树映射超出了GC开销限制,java,hibernate,garbage-collection,out-of-memory,Java,Hibernate,Garbage Collection,Out Of Memory,我一直在获取java.lang.OutOfMemoryError:从Hibernate查询加载行时超出了GC开销限制 我试过几次增加记忆,但这种情况还在继续。我在日志中注意到,它似乎指向一个方法,我正在使用TreeMap。我想知道是否我使用这个错误导致了内存不足问题 public List<Item> getProducts() { List<ProductListing> productListings = session.createCriteria(Prod

我一直在获取
java.lang.OutOfMemoryError:从Hibernate查询加载行时超出了GC开销限制

我试过几次增加记忆,但这种情况还在继续。我在日志中注意到,它似乎指向一个方法,我正在使用
TreeMap
。我想知道是否我使用这个错误导致了内存不足问题

public List<Item> getProducts() {
    List<ProductListing> productListings = session.createCriteria(ProductListing.class)
    .createAlias("productConfiguration", "productConfiguration")
    .add(Restrictions.eq("productConfiguration.category", category))
    .add(Restrictions.eq("active", true))
    .add(Restrictions.eq("purchased", true)).list();

    Map<String, Item> items = new TreeMap<>();

    productListings.stream().forEach((productListing) -> {
        Item item = productListing.getItem();
        items.put(item.getName(), item);
    });

    return new ArrayList<>(items.values());
}
public List getProducts(){
List productListings=session.createCriteria(ProductListing.class)
.createAlias(“产品配置”、“产品配置”)
.add(Restrictions.eq(“productConfiguration.category”,category))
.add(Restrictions.eq(“活动”,真))
.add(Restrictions.eq(“已购买”,true)).list();
映射项=新树映射();
productListings.stream().forEach((productListing)->{
Item=productListing.getItem();
items.put(item.getName(),item);
});
返回新的ArrayList(items.values());
}
  • 将值传递到arraylist是否安全

  • 我需要设置arraylist大小吗

我只是想知道我是不是做错了什么。它看起来是正确的,但内存异常则相反。

我称之为“加载世界”-名称
getProducts()
(不带参数)有点代码味道-因为您没有限制结果集的大小,而且据我们所知,您的
对象可能很大,具有大量急切加载的依赖项(更不用说堆上的所有备份Hibernate对象)

另一个大问题是,将脱水实体添加到
TreeMap
,调用
hashCode()
,并可能调用
equals()
,结果是扔掉键并将值复制到新分配的
ArrayList

撇开
ArrayList
没有预先调整大小不谈(没错,这并不理想,尽管它应该只是很慢),为什么要进行
TreeMap
阶段?如果需要进行聚合,为什么不让数据库更有效地进行聚合(例如,通过
按名称分组
)并且使用索引,而不是将其全部拉到地图中进行慢得多的重新处理?至少,通过只返回唯一的
s,您可以跳过地图阶段,直接复制到列表中(根据您的需要,还有更轻量级的可能性)

我强烈建议使用合适的探查器进行测试。特别是,它可以帮助您确定紧急加载对堆大小的影响。关闭该选项可能会使问题更易于管理


但是,你也需要考虑你的代码的客户:谁实际上需要< <强> >所有> /强>那些<代码>项目>代码> s?很可能没有人。

谢谢,我重新设计了所有的东西并把它移动到一个查询中。更好的是,问题解决了。