中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何淺談Java性能優化中的函數

發布時間:2021-11-26 10:24:27 來源:億速云 閱讀:199 作者:柒染 欄目:編程語言

如何淺談Java性能優化中的函數,很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細講解,有這方面需求的人可以來學習下,希望你能有所收獲。

★finalize 函數的調用機制

  俺經常啰嗦:“了解本質機制的重要性”。所以今天也得先談談 finalize 函數的調用機制。在聊之前,先聲明一下:Java虛擬機規范,并沒有硬性規定垃圾回收該不該搞,以及該如何搞。所以俺這里提到的 finalize 函數的調用機制,或許適用于大多數 JVM,但【不保證】適用于所有的 JVM。

◇何時被調用?

  finalize 啥時候才會被調用捏?一般來說,要等到JVM開始進行垃圾回收的時候,它才【有可能】被調用。而 JVM 進行垃圾回收的時間點是【非常】不確定的,依賴于各種運行時的環境因素。正是由于 finalize 函數調用時間點的不確定,導致了后面提到的某些缺點。

◇誰來調用?

  說完何時調用,咱接著來聊一下被誰調用?
  常見的 JVM 會通過 GC 的垃圾回收線程來進行 finalize 函數的調用。由于垃圾回收線程比較重要(人家好歹也是 JVM 的一個組成部分嘛),為了防止 finalize 函數拋出的異常影響到垃圾回收線程的運作,垃圾回收線程會在調用每一個 finalize 函數時進行 try/catch,如果捕獲到異常,就直接丟棄,然后接著處理下一個失效對象的 finalize 函數。

★對 finalize 函數的誤解和誤用

◇把 finalize 理解為“析構函數”

  學過 C++ 的同學應該都知道“析構函數”(不懂 C++ 的同學直接跳過此小節)。C++ 析構函數是在對象離開作用域的當口,【立即】被調用的。
  很多從 C++ 轉 Java 的同學會想當然地把 Java 的 finalize 函數牽強附會成 C++ 的析構函數(兩者確實有某些相似之處)。然而,現實往往不是這么美好滴。由于 Java 的 finalize 函數和 C++ 的析構函數之間有許多非常【關鍵性】的差異,那些把 finalize 拿來當析構函數用的同學,是注定要碰壁滴(具體請看本文后面“finalize 函數的缺點”)。

◇依靠 finalize 來釋放資源

  很多同學寄希望于通過 finalize() 來完成類對象中某些資源的釋放(比如關閉數據庫連接之類)。
  有這種企圖的同學,請注意看本文后面的“finalize 函數的缺點”!

★使用 finalize 函數的注意事項

  下面介紹的注意事項,有些可能和性能優化關系不大,俺也一并列出來。

◇調用時間不確定——有資源浪費的風險

  前面已經介紹了調用機制。同學們應該認清【finalize 的調用時機是很不確定的】這樣一個事實。所以,假如你把某些稀缺資源放到 finalize() 中釋放,可能會導致該稀缺資源等上很久很久很久以后才被釋放。這可是資源的浪費啊!
  另外,某些類對象所攜帶的資源(比如某些 JDBC 的類)可能本身就很耗費內存,這些資源的延遲釋放會造成很大的性能問題。

◇可能不被調用——有資源泄漏的風險

  很多同學誤以為 finalize() 總是會被調用,【其實不然】。在某些情況下,finalize() 壓根兒不被調用。比如在 JVM 退出的當口,內存中那些對象的 finalize 函數可能就不會被調用了。
  俺估摸著:還有同學在打 “runFinalizersOnExit” 的主意,來確保所有的 finalize 在 JVM 退出前被調用。但是,很可惜也很遺憾,該方法從 JDK 1.2 開始,就已經被廢棄了。即使該方法不被廢棄,也是有很大的線程安全隱患滴!企圖打這個主意的同學,趁早死了這條心吧!
  從上述可以看出,一旦你依賴 finalize() 來幫你釋放資源,那可是很不妙啊(【有資源泄漏的危險】)!很多時候,資源泄露導致的性能問題更加嚴重,萬萬不可小看。

◇對象可能在 finalize 函數調用時復活——有詐尸的風險

  詐尸的情況比較少見,不過俺還是稍微提一下。
  本來,只有當某個對象已經失效(沒有引用),垃圾回收器才會調用該對象的 finalize 函數。但是,萬一碰上某個變態的程序員,在 finalize() 函數內部再把對象自身的引用(也就是 this)重新保存在某處,也就相當于把自己復活了(因為這個對象重新有了引用,不再處于失效狀態)。這種做法是不是夠變態啊 :-)
  為了防止發生這種詭異的事情,垃圾回收器只能在每次調用完 finalize() 之后再次去檢查該對象是否還處于失效狀態。這無形中又增加了 JVM 的開銷。
  隨便提一下。由于 JDK 的文檔中規定了,JVM 對于每一個類對象實例最多只會調用一次 finalize()。所以,對于那些詐尸的實例,當它們真正死亡時,finalize() 反而不會被調用了。這看起來是不是很奇怪?

◇要記得自己做異常捕獲

  剛才在介紹 finalize() 調用機制時提到,一旦有異常拋出到 finalize 函數外面,會被垃圾回收線程捕獲并丟棄。也就是說,異常被忽略掉了。為了防止這種事兒,凡是 finalize() 中有可能拋出異常的代碼,你都得寫上 try catch 語句,自己進行捕獲。

◇要小心線程安全

  由于調用 finalize() 的是垃圾回收線程,和你自己代碼的線程不是同一個線程;甚至不同對象的 finalize() 可能會被不同的垃圾回收線程調用(比如使用“并行收集器”的時候)。所以,當你在 finalize() 里面訪問某些數據的時候,還得時刻留心線程安全的問題。

  前面廢了這么多話,最后稍微總結一下。我以為:finalize 實在是 Java 的雞肋。

看完上述內容是否對您有幫助呢?如果還想對相關知識有進一步的了解或閱讀更多相關文章,請關注億速云行業資訊頻道,感謝您對億速云的支持。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

石泉县| 肥西县| 峡江县| 东乡| 同仁县| 绥江县| 习水县| 大化| 镇江市| 磐安县| 专栏| 赤城县| 湘潭县| 丰城市| 宁都县| 新源县| 宝丰县| 浪卡子县| 宝鸡市| 凉城县| 田阳县| 邳州市| 双牌县| 临漳县| 泗洪县| 霍山县| 柘荣县| 茶陵县| 云梦县| 独山县| 石家庄市| 湖口县| 巴彦县| 四平市| 广德县| 铁岭县| 曲沃县| 棋牌| 梁平县| 泉州市| 西安市|