什么是PermGen泄漏?

泄漏樣品 接下來是對Java應用程序中特定類型的內存問題的實用介紹。 即–我們將分析導致java.lang.OutOfMemoryError:PermGen空間的錯誤 堆棧跟蹤中的癥狀。

首先,我們將介紹理解該主題所需的核心概念,并說明什么是對象,類,類加載器和JVM內存模型。 如果您熟悉基本概念,則可以直接跳到下一部分,在此我將描述所討論錯誤的兩種典型情況以及解決它的提示和建議。

對象,類和類加載器

好吧,我不會從最基本的內容開始。 我想如果您已經找到我們,那么您應該熟悉Java中的一切都是Object的概念。 并且所有對象均由其類指定。 因此,每個對象都有對java.lang.Class實例的引用,該實例描述了該對象的類的結構。

但是,當您在代碼中創建一個新對象時,實際上發生了什么呢? 例如,如果您寫的東西真的很復雜

人老板=新人()

Java虛擬機(JVM)需要了解要創建的對象的結構。 為此,JVM查找名為Person的類。 而且,如果在程序的特定執行期間第一次訪問Person類,則通常必須從JVM從相應的Person.class文件中加載它。 在驅動器上查找Person.class文件,將其加載到內存中并解析其結構的過程稱為類加載 。 確保正確的類加載過程是ClassLoader的責任 ClassLoader是java.lang.ClassLoader類的實例,Java程序中的每個類都必須由某個ClassLoader進行加載。 結果,我們現在具有以下關系:

關系

從下圖可以看到,每個類加載器均包含對其已加載的所有類的引用。 就本文而言,這些關系非常有趣。

參考資料

記住此圖像,稍后我們將需要它。

永久世代

如今,幾乎每個JVM都使用一個單獨的內存區域(稱為Permanent Generation(簡稱PermGen ))來保存Java類的內部表示形式。 PermGen還用于存儲更多信息-如果您有興趣,請從這篇文章中查找詳細信息-但對于我們的文章,可以安全地假設僅類定義存儲在PermGen中。 在運行Java 1.6的兩臺計算機上,該區域的默認大小不是非常可觀的82MB。

正如我在之前的一篇文章中所解釋的那樣,Java中的內存泄漏是一種情況,其中某些對象不再被應用程序使用,但是垃圾收集器無法將其識別為未使用。 如果那些未使用的對象對堆使用的貢獻很大,以致于應用程序無法滿足下一個內存分配請求,則會導致OutOfMemoryError

java.lang.OutOfMemoryError:PermGen空間的根本原因是完全相同的:JVM需要加載新類的定義,但是PermGen中沒有足夠的空間來執行此操作–那里已經存儲了太多的類。 可能的原因是,您的應用程序或服務器使用了太多的類,而PermGen的當前大小無法容納它們。 另一個常見原因可能是內存泄漏。

永久泄漏

但是,仍然有可能在PermGen中泄漏某些東西嗎? 它保存著Java類的定義,它們不能成為未使用的,可以嗎? 實際上,他們可以。 如果將Java Web應用程序部署到應用程序服務器中,則在取消部署應用程序時,EAR / WAR中的所有這些類將變得毫無用處。 由于應用程序服務器仍處于活動狀態,因此JVM繼續運行,但是不再使用大量的類定義。 并且應該將它們從PermGen中刪除。 如果沒有,我們將在PermGen區域發生內存泄漏。

作為一個很好的例子,Tomcat開發人員已經建立了一個Wiki頁面,描述了在Apache Tomcat 6.0.24及更高版本中發現并修復的各種漏洞。

泄漏線程

類加載器泄漏的一種可能情況是長時間運行的線程。 當您的應用程序或您的應用程序使用的第三方庫(通常以我的經驗)啟動某個長時間運行的線程時,就會發生這種情況。 一個例子就是計時器線程,其任務是定期執行一些代碼。

如果該線程的預期壽命不確定,我們將直接陷入麻煩。 當應用程序的任何部分啟動線程時,必須確保它不會使應用程序壽命更長。 在典型情況下,開發人員要么不了解此責任,要么干脆忘了編寫清理代碼。

否則,如果在取消部署應用程序后某個線程繼續運行,則通常將保留對由其啟動的Web應用程序的類加載器的引用,稱為上下文類加載器 。 反過來,這意味著未部署的應用程序的所有類都繼續保留在內存中。 補救? 如果是您的應用程序啟動了新線程,則應在取消部署期間使用servlet上下文偵聽器將其關閉。 如果它是第三方庫,則應搜索其自己的特定關閉掛鉤。 或提交錯誤報告(如果沒有)。

驅動程序泄漏

數據庫驅動程序可能導致泄漏的另一種典型情況。 我們在Plumbr附帶的演示應用程序中遇到了此泄漏。 它是隨Spring MVC一起提供的經過稍微修改的Pet Clinic應用程序。 讓我們重點介紹將應用程序部署到服務器時發生的一些事情。

  • 服務器創建一個新的java.lang.Classloader實例,并開始使用它加載應用程序的類。
  • 由于PetClinic使用HSQL數據庫,因此它將加載相應的JDBC驅動程序org.hsqldb.jdbcDriver
  • 此類是一種很好的JDBC驅動程序,根據JDBC規范的要求,在初始化期間將其自身注冊到java.sql.DriverManager 。 該注冊包括在DriverManager的靜態字段中存儲對org.hsqldb.jdbcDriver實例的引用。

現在,當從應用程序服務器取消部署應用程序時, java.sql.DriverManager仍將保留該引用,因為HSQLDB庫,Spring框架或應用程序中都沒有刪除該代碼的代碼! 如上文所述, jdbcDriver對象仍然持有對org.hsqldb.jdbcDriver類的引用,而該類又持有對用于加載應用程序的java.lang.Classloader實例的引用。 現在,該類加載器仍引用應用程序的所有類。 對于我們特定的演示應用程序,在應用程序啟動期間將加載近2000個類,在PermGen中大約占用10MB。 這意味著需要大約5到10個重新部署才能用默認大小填充PermGen,以達到java.lang.OutOfMemoryError:PermGen空間崩潰。

如何解決? 一種可能性是編寫一個Servlet上下文偵聽器,該偵聽器在應用程序關閉期間從DriverManager注銷HSQLDB驅動程序。 這很簡單。 但是請記住–您將必須使用驅動程序在每個應用程序中編寫相應的代碼。

使用我們的演示應用程序下載我們最新版本的Plumbr,并使用它來查找泄漏的發生方式,Plumbr如何發現泄漏以及如何解釋原因。

結論

您的應用程序可能遇到java.lang.OutOfMemoryError:PermGen space的原因很多。 導致它們大多數的根本原因是對由應用程序的類加載器加載的對象或類的引用,這些對象或類在此之后死亡。 或直接鏈接到類加載器本身。 對于大多數這些原因,您需要采取的補救措施非常相似。 首先,找出引用在哪里保存。 其次,向您的Web應用程序添加一個關閉掛鉤,以在取消部署應用程序時刪除引用。 您可以通過使用Servlet上下文偵聽器或通過第三方庫提供的API來實現。

找到那些泄漏的參考從未如此簡單。 我們自己花費了無數的時間試圖找出為什么某些應用程序每次重新部署都需要20MB的PermGen。 但是從1.1版開始,Plumbr將向您顯示泄漏的原因,并提示您如何修復它。 如果您想嘗試一下,請注冊并下載該工具 。 如果您運行的是Plumbr的舊版本,我們強烈建議您下載升級程序 。

參考: 什么是PermGen泄漏? 由我們的JCG合作伙伴 Nikita Salnikov Tarnovski在Plumbr Blog博客上獲得。

翻譯自: https://www.javacodegeeks.com/2012/12/what-is-a-permgen-leak.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/370778.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/370778.shtml
英文地址,請注明出處:http://en.pswp.cn/news/370778.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

html浮動炫酷樣式,jQuery和CSS3炫酷表單浮動標簽特效

這是一款炫酷的jQuery和CSS3表單浮動標簽特效。浮動標簽是指輸入框中的文字或占位文本在輸入框聚焦的時候,以動畫的方式浮動到指定的地方。浮動標簽特效是一種新穎時尚的動畫特效,不僅效果很酷,而且能以明確的方式提示用戶該輸入框應該填寫上…

rto凈化效率計算公式_全面剖析 石油化工行業RTO蓄熱式焚燒爐的優勢要素

在我國的國民經濟發展中,石油化工產業是重要的能源基礎工業,但是廢氣的治理問題一直困擾著許多企業。直到RTO蓄熱式焚燒爐的面世,為石油化工行業的廢氣治理帶來了新希望。如今,有機廢氣治理工作越來越受到廣泛重視,傳統…

python作業:高級FTP程序

要求: 用戶加密認證允許同時多用戶登錄每個用戶有自己的家目錄 ,且只能訪問自己的家目錄對用戶進行磁盤配額,每個用戶的可用空間不同允許用戶在ftp server上隨意切換目錄允許用戶查看當前目錄下文件允許上傳和下載文件,保證文件一…

webpack學習筆記 (一)

一、安裝nodejs; 點擊打開nodejs官方站點; 點擊下圖框住的按鈕,下周nodejs安裝包; 安裝下載好的安裝包。 安裝完畢之后,在cmd中輸入node -v查看是否已經安裝成功 如果有版本號顯示,則代表安裝成功&#xf…

將渦輪增壓器添加到JEE Apps

我扮演的關鍵角色之一是在本地社區中傳播Akka。 作為討論的一部分,人們通常會想到的問題/疑問是Akka如何針對編寫良好的Java / JEE應用程序提供更好的可伸縮性和并發性。 由于底層硬件/ JVM保持不變,因此參與者模型如何比傳統的JEE應用程序發揮更多的功…

python package_python之package定義

一.簡單說明 python是通過module組織代碼的,每一個module就是一個python文件,但是modules是通過package來組織的。我們平時在簡單測試的時候 一般就是幾個Python文件存放在同級的目錄下,但是當我們開始嘗試開發更為復雜的項目時,p…

html 手機端無法拖動地圖,關于騰訊地圖api的禁止地圖拖動問題

禁用滾動和拖動*{margin:0px;padding:0px;}body, button, input, select, textarea {font: 12px/16px Verdana, Helvetica, Arial, sans-serif;}p{width:603px;padding-top:3px;overflow:hidden;}.btn{width:142px;}#container{min-width:600px;min-height:767px;}//初始化函數…

《一起》個人進展——Day07

昨天做了些什么:實現登錄界面的美化 今天的計劃:還是準備進行與其他界面的融合 遇到的困難:代碼了解不夠,融合起來會出現bug轉載于:https://www.cnblogs.com/gxt-/p/6828131.html

epoll nio區別_【總結】兩種 NIO 實現:Selector 與 Epoll

我想用這個話題小結下最近這一階段的各種測試和開發。其實文章的內容主要還是想總結一下NIO Socket,以及兩種不同操作系統實現NIO的方式,selector和epoll。問題應該從服務器端開始說起。我們都寫過net包下的socket,用socket的accept方法來等待…

MapReduce的工作原理

一、MapReduce模型框架 MapReduce是一個用于大規模數據處理的分布式計算模型,最初由Google工程師設計并實現的,Google已經將完整的MapReduce論文公開發布了。其中的定義是,MapReduce是一個編程模型,是一個用于處理和生成大規模數據…

react實現多行文本超出加省略號

http://www.css88.com/archives/5206 overflow : hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; 根據該文章方法,放在react項目中發現并不能實現,仔細觀察發現原來react解析出來的css樣…

Google Guava MultiMaps

番石榴 這是系列文章中的第一篇,我將嘗試解釋和探索Google很棒的Guava java庫 。 我在搜索Apache Commons Collections的通用版本時遇到了番石榴(Guava)–我需要一個Bimap并且厭倦了必須使用強制類型轉換來填充我的代碼–但是我發現要好得多…

qq群 html,我的群組-普通群組.html

我的群組-普通群組$axure.utils.getTransparentGifPath function() { return resources/images/transparent.gif; };$axure.utils.getOtherPath function() { return resources/Other.html; };$axure.utils.getReloadPath function() { return resou…

查看PLC IP 端口_西門子828D數控系統X130接口通訊怪異現象(X130手動設置的 IP)...

西門子828D數控系統,調試PLC過程中遇到網絡通信怪異問題(不能直連非要加個路由器),筆記本電腦的以太網網絡直接連接顯示網絡電纜被拔出,如下圖所示:奇怪,怎么出現這種情況了呢,因為我用這臺電腦調試過別的P…

基于嵌入式系統的gnash最小庫依賴關系

已經對gnash的依賴庫作了詳細的分析,下邊是必須依賴的庫:GIF Required libungif-devlibxml2 Required libxml2-devPNG Requir…

git 創建webpack項目_一次create-react-app創建項目升級webpack的流水賬

不再贅述為什么要升級webpack4,有興趣的小伙伴可以看一下 知乎:如何評價webpack4下面擼起袖子開干:克隆項目,新建分支git checkout -b feature_webpack_upgrade# 相當于以下兩句的簡寫git branch feature_webpack_upgradegit chec…

bzoj1263

貪心 n%31 分出一個4&#xff0c;其余用3&#xff0c;n%32&#xff0c;分出一個2&#xff0c;其余用3&#xff0c;然后高精度就行了 #include<bits/stdc.h> using namespace std; const int N 5005; struct BigInt {int len;int a[N];BigInt() { memset(a, 0, sizeof(a)…

c語言volatile_[技術]為什么單片機C語言編程時某一變量有時亂碼

最近一個項目里面&#xff0c;在KEIL中用C語言在單片機里面定義了一個狀態機全局變量&#xff0c;這個變量隨時會改變&#xff0c;用于切換觸摸屏的界面&#xff0c;可是程序運行中出現了一個問題&#xff0c;這個狀態機號總是出現了被莫名奇妙改變的問題&#xff0c;導致觸屏不…

沙箱Java代碼

在上一篇文章中&#xff0c;我們研究了如何保護移動Java代碼 。 這樣做的一種選擇是在籠子或沙箱中運行代碼。 這篇文章探討了如何為Java應用程序設置這樣的沙箱。 安全經理 Java中支持沙箱的安全性設施是java.lang.SecurityManager 。 默認情況下&#xff0c;Java在沒有Se…

微型計算機2017年9月上,2017年9月計算機一級考試WPS Office沖刺題

2017年9月計算機一級考試WPS Office沖刺題2017年下半年計算機一級考試將在9月份進行&#xff0c;為了方便考生備考計算機一級考試。下面是小編為大家帶來的計算機一級考試WPS Office沖刺題&#xff0c;歡迎閱讀。沖刺題一&#xff1a;1、PowerPoint 演示文稿和模板的擴展名是【…