2014-09-19 39 views
2

flush docs的javasession.flush如何幫助內存釋放?

沖洗聲明是同步基礎持久 存儲在存儲器中保持持久化狀態的過程。

這裏是我的上述聲明

的理解所以,如果有人做 插入/更新,然後沖洗,額外插入的行會趴在只有Java內存 。但是其他方式,例如Db數據只會與僅在提交時保存在內存中的持久狀態同步的 。

現在讓上述認識

去了我整個HIbernate commit() and flush()從哪裏來accepeted答案告訴 調用Session.flush有助於在某些情況下釋放內存,從而避免OutOfMemoryException異常。

當我做以下,一號線(調用Session.flush())將執行的客戶表20級的客戶其 釋放的名單,但是,從另一方面20個客戶對象的內存中創建20個客戶數據行 插入查詢在客戶表下仍然存在於java內存中(它只會在第2行提交時纔會到數據庫)。所以我不確定 session.flush如何幫助釋放內存?

Session session = sessionFactory.openSession(); 
Transaction tx = session.beginTransaction(); 


for (int i=0; i<100000; i++) { 
    Customer customer = new Customer(.....); 
    session.save(customer); 
    if (i % 20 == 0) { //20, same as the JDBC batch size 
     //flush a batch of inserts and release memory: 
     session.flush(); //line1 
     session.clear(); 
    } 
} 

tx.commit();// line2 
session.close(); 

回答

0

按照API session.flush()

void flush() 
      throws HibernateException 

隊這屆沖洗。在提交事務並關閉會話 (取決於flush-mode,Transaction.commit()調用此方法)之前,必須在單位 工作的末尾調用。

刷新是同步存儲器中持久狀態的基礎持久性存儲過程。

因此,此方法的目的是使持久狀態與基礎數據庫同步。如果你仍然有對象的引用,它將無助於釋放內存。

也請參考此鏈接 - Hibernate out of memory exception while processing large collection of elements

如果在你的程序要創建100000Customerfor-loop。如果沒有hibernate代碼,那麼這意味着你沒有維護這些對象的任何引用,因此它們有資格進行垃圾回收。

但是,當你說session.save(customer)時,對象與Hibernate的會話相關聯,因此它們將被放置在一級緩存中。

如果對象的數量增加並且沒有足夠的內存,那麼隨着hibernate嘗試將所有這些對象保存在內存中,您將遇到內存不足的問題。因此調用flush方法將使hibernate調用所需的數據庫查詢,並調用clear將幫助它釋放第一級緩存中的內存,從而釋放一些內存。

更新:

調用session.clear()使冬眠清除內存,它在內部一級緩存的形式保存。 session.clear()撥打StatefulPersistenceContext.clear()撥打電話clear() method on various Map's和其他對象。這將清除一級緩存中的內存。這清楚地表明對象有資格進行垃圾收集,這有助於釋放一些內存。所以狀態不再由Hibernate維護,因此對象處於分離狀態。

現在,作爲每API Traansaction.commit();

void commit() 
      throws HibernateException 

沖洗相關的會話,並結束工作單元(除非在我們是FlushMode.MANUAL

此方法將提交基礎交易當且僅當 基本交易由此物件啓動時。

調用commit()刷新所有未決項目,然後發出commit到底層數據庫。

更新:

也可參考此鏈接 - Flushing the session,它明確地說,當我們調用flush()方法JDBC調用製成。

有時候,Session會執行需要 SQL語句同步JDBC連接與對象的狀態狀態保存在內存中 。這個過程稱爲刷新。

除了在顯式刷新()時外,關於Session何時執行JDBC調用的絕對沒有保證 ,只有 執行它們的順序。

+0

請看我更新的帖子。 – 2014-09-19 10:15:34

+0

@MSach,更新了我的答案和更多細節,請檢查是否有幫助。 – Chaitanya 2014-09-19 10:52:59

+0

你說過「flush方法會讓hibernate調用所需的數據庫查詢」。那就是我所懷疑的。 它不調用物理數據庫上的所需查詢,而是調用java內存中保存的數據庫表(持久狀態)。 – 2014-09-19 11:16:58

0

flush()會將數據發送到數據庫。你會看到,如果你在Hibernate中激活SQL日誌記錄。 commit()將提交以前發送到數據庫的更改。它可能是,你的緩存保存全部或部分數據。在這種情況下,你必須調整你的緩存設置。這就是說,如果你在內存中有很多改變的或新的對象,你需要做一個flush來避免OutOfmemoryError,那麼很可能你需要在更深層次上改變你的設計,比如做多個但是小的事務。有了這樣大的交易可以給你的應用程序和數據庫帶來問題。