2016-11-02 41 views
9

我一直在遇到問題,確保我正在銷燬的彈簧應用程序上下文已經完全消失,並且看不到垃圾收集對象。當我查看VisualVM中的實例時,我可以看到有一些對上下文和它的bean工廠的未完成引用,一旦上下文被關閉並銷燬,它們就會保留。這些都與bean工廠的初始設置(在AbstractApplicationContext的刷新方法期間)有關,該工廠使用各種bean後期處理器來註冊bean工廠和上下文等。乾淨地銷燬Spring應用程序上下文

似乎沒有任何方法在bean工廠或應用程序上下文(甚至是可刷新的上下文)上,它們除了刪除對bean工廠的最低級別引用外。其結果是它似乎在泄漏內存,並且在某些情況下阻止了上下文的清潔重新創建。

我問,因爲我是做什麼工作的可以動態地創建/銷燬,然後重新創建上下文(如模塊動態加載和卸載)和上下文和豆腐廠的剩餘元素是造成軟件組件的問題,例如spring-data-jpa(尤其是將存儲庫接口綁定到存儲庫實現的代理)。

有沒有人知道一種方式,我可以清理並完全刪除上下文和bean工廠,而不必完全關閉最初創建它的虛擬機?

回答

0

如果您在非web應用程序環境中使用Spring的IoC容器,例如,在富客戶端桌面環境中;您使用JVM註冊了一個關閉鉤子。這樣做可以確保正常關閉並在單例bean上調用相關的銷燬方法,從而釋放所有資源。當然,您仍然必須正確配置和實施這些銷燬回調。

要註冊一個關閉掛鉤,你應該叫即宣告對AbstractApplicationContextregisterShutdownHook()方法:

代碼上下文

import org.springframework.context.support.AbstractApplicationContext; 
import org.springframework.context.support.ClassPathXmlApplicationContext; 

public final class startup { 

    public static void main(final String[] args) throws Exception { 
     AbstractApplicationContext ctx 
      = new ClassPathXmlApplicationContext(new String []{"beans.xml"}); 

     // add a shutdown hook for the above context... 
     ctx.registerShutdownHook(); 

     // app runs here... 

     // main method exits, hook is called prior to the app shutting down... 
    } 
} 
+0

謝謝,但正如我所提到的,這與整個容器的關閉無關。這是一個應用程序上下文的創建/銷燬而不關閉容器,因此關閉鉤子不會有幫助。 – Mike

0

呼叫destroy,並設置爲null引用實例的所有變量您的應用上下文:

AbstractApplicationContext context = new ClassPathXmlApplicationContext(new String []{"beans.xml"}); 

// ... do your stuff 

context.destroy(); 
context = null; 
+0

謝謝,但我已經考慮到破壞,它只是作爲一個非常特殊的情況(其中一個上下文是另一個bean工廠內的一個bean),並且在任何情況下,默認實現只是調用close();我最明確地關閉了上下文並刪除了對上下文的任何引用,但問題在於,應用程序上下文中的bean工廠在Spring中註冊了自己(或由其註冊)了許多其他內部實例,因此整體引用永遠不會發布(在我們的代碼中將它設置爲null無效。 – Mike

1

有looke最近我又注意到,我注意到我重寫了上下文的doClose()方法以確保豆被完全銷燬,但沒有調用super.doClose()方法,這意味着LiveBeansView.unregisterApplicationContext()/destroyBeans()/getLifecycleProcessor().onClose()closeBeanFactory()沒有被調用。

我加了這個,並且(大部分)如果不是所有的上下文現在都被幹淨的銷燬和垃圾收集。我將假設任何未被銷燬的未解決的上下文都可能是我們自己的代碼中懸而未決的引用的問題。

相關問題