![](/img/trans.png)
[英]Java PreparedStatement java.lang.OutOfMemoryError: GC overhead limit exceeded
[英]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.