當重新加載JSP時(我正在談論內部體系結構),類重新加載在Tomcat中如何工作?用於JSP的Tomcat類重新加載
我知道每個JSP都被編譯爲一個Java類。但是,類加載器(每個Web應用程序都是唯一的)如何重新加載這些生成的類,因爲類加載器不允許類卸載並且不會收集太多垃圾?
當重新加載JSP時(我正在談論內部體系結構),類重新加載在Tomcat中如何工作?用於JSP的Tomcat類重新加載
我知道每個JSP都被編譯爲一個Java類。但是,類加載器(每個Web應用程序都是唯一的)如何重新加載這些生成的類,因爲類加載器不允許類卸載並且不會收集太多垃圾?
如果您想要接受教育,請閱讀代碼。
我已經檢查了代碼。但是,我不明白的是:在Java中,每個類加載器都有一個加載類的列表(請參閱ClassLoader中的私有屬性類)。 addClass方法是唯一一個將類添加到此屬性並由JVM調用的方法。這樣,每個Class對象至少引用它並且沒有反射,自定義類加載器不能刪除這個引用。據我所知,Java中的想法是強制GC卸載一個類,直到它卸載了首先加載它的類加載器。 –
(續)我檢查了Tomcat如何加載類我無法從ClassLoader中找到對屬性類的引用。所以,我的理解是,一旦類被加載,一個類實際上永遠不會被卸載。所以,最終,這應該導致與內存相關的錯誤。我很好奇Tomcat不能到達這裏。 –
標準的Java類加載器永遠不會卸載一個類。 Tomcat有它自己的類加載器,它可以用一個新實例替換一個類的舊實例,然後孤立舊實例,以通常的方式將它提供給垃圾收集器。
沿線的某處我看到,如果某個類未在指定的時間段內使用,Tomcat將卸載它。但目前我找不到任何參考。
JasperLoader實例是加載jsp生成的servlet的類加載器。
jsp編譯器在生成較新的servlet類文件時「丟棄」(設置爲null)舊的JasperLoader實例。從評論
報價在JspServletWrapper.setServletLastModifiedTime:
真的需要卸載舊的類,但不能這樣做。做 是扔掉JspLoader所以 一個新的加載器將被創建,這將加載新的 類。
對於「沒有收集太多垃圾」我會持不同意見,因爲Tomcat因其幾次重新部署後內存不足而聞名。 – maksimov
是的@maksimov,你是對的。也許我還應該添加一個問題來問一下Tomcat的策略是什麼,以減少發生內存不足錯誤的可能性。 –
關於[Tomcat]的一些信息(http://tomcat.apache.org/tomcat-5.5-doc/jasper-howto.html)。有趣的是,他們正在使用ECJ增量編譯器來編譯它們的JSP。 – maksimov