java defunct產生的原因和解決辦法:
在很多時候,我們啟動JAVA進程后,假如退出這個JAVA進程,在系統進程中仍然可以看到這個進程.
這種情況一般出現在UNIX/linux系統,對于WIN平臺出現情況較少.
這個進程在UNIX平臺上,你即使kill進程號也不能殺掉它,但它仍然占用系統資源,成了真正的"僵尸"。
產生的原因:
以前我們下載JDK時,可以下載到JDK的SRC然后自己編譯,現在的官方網站上已經找不到可以自己編
譯的JDK包,下載回來的JDK都是釋放包,我們可以想象,無論SUN在發布JDK時考慮得如何完美,本地
庫都不可能完全和當前系統的版本號完全一致。舉個例子,假如System.gc()調用了本地庫glic6.0.2.so
那么在當前系統上沒有這個版本的庫或沒有這個版本的庫的鏈結,那么gc()方法肯定不能正確工作。
當然sun在發布的時候可能會把這個本地庫打包在JDK發行包中,但glic6.0.2.so中又調用了其它庫,如
subglic6.0.21.so,即使系統中存在完全相同的glic6.0.2.so,但你無法確認它調用的庫又完全匹配,
事實上這幾乎是不可能完全匹配的。
正是這樣本地庫版本號的不一致,才使得需要調用本地庫的JVM底層功能不能正確工作,所以清除,
退出進程等工作就可能無法完成,產生了java defunct。
知道了問題的原因,就能從多方面解決了。假如我們的JDK的src版進行編譯安裝而不是用SUN提供好的
本地庫,當然不會存在上面的問題,但現在好象已經不提供src編譯安裝的發布包了,所以指定內核版本
號,以便使它和JDK發布時使用的版本相一致,可以基本解決java defunct。
假如你不知道當前JDK的本地庫是基于什么內核版本號發布的,一般來說,應該提供系統當前的內核版本號:
在Linux下,先查看當前的內核版本:
uname -r
2.4.21-4.EL
把主版本號COPY下來,調用:
LD_ASSUME_KERNEL=2.4.21-4
eXPort LD_ASSUME_KERNEL
假如你知道某個版本的JDK中的本地庫是基于某個內核版本發而布的那你可以直接指定LD_ASSUME_KERNEL為
這個版本,這樣會獲得最大的一致性
新聞熱點
疑難解答