簡體   English   中英

異常java.lang.OutOfMemoryError:樹映射超出了GC開銷限制

[英]Exception java.lang.OutOfMemoryError: GC overhead limit exceeded with tree map

我一直得到java.lang.OutOfMemoryError: GC overhead limit exceeded從Hibernate查詢加載行時java.lang.OutOfMemoryError: GC overhead limit exceeded

我已經嘗試過幾次增加內存並且它會繼續發生。 我在日志中注意到它似乎指向了一個我使用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());
}
  • 將值傳遞給arraylist是否安全?

  • 我需要設置arraylist大小嗎?

我只是想知道我是否正在做一些非常錯誤的事情。 它看起來是正確的,但內存異常另有說法。

我稱之為“加載世界” - 名稱getProducts() (沒有args)有點代碼味道 - 因為你沒有限制結果集大小,而且我們知道你的所有Item對象都可能很大許多急切加載的依賴項(更不用說堆上的所有后備Hibernate對象)。

另一個大問題是,您將脫水實體添加到TreeMap ,調用hashCode()並可能equals() ,只是丟棄密鑰並將值復制到新分配的ArrayList

暫且不考慮ArrayList的預先調整(正確,這不理想,雖然它應該只是很慢),為什么TreeMap階段? 如果您需要進行聚合,為什么不讓數據庫更有效地(例如通過GROUP BY name )和使用索引,而不是將其全部拉入地圖以進行更慢的重新處理? 至少,通過僅返回唯一的Item ,您可以跳過地圖階段並直接復制到您的列表中(根據您的需要,甚至還有更輕量級的可能性)。

我強烈建議使用合適的Profiler進行測試。 具體來說,它可以幫助您確定預先加載對堆大小的影響。 可能只是關閉它可能會使問題更易於管理。

但是,您還需要考慮代碼的客戶端:誰真正需要所有這些Item 最有可能沒有人。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM