jprofilerlinux
① tomcat編譯內存溢出怎麼解決
JVM管理兩種類型的內存,堆和非堆。堆是給開發人員用的上面說的就是,是在JVM啟動時創建;非堆是留給JVM自己用的,用來存放類的信息的。它和堆不同,運行期內GC不會釋放空間。 一、內存溢出類型
1、java.lang.OutOfMemoryError: PermGen space
JVM管理兩種類型的內存,堆和非堆。堆是給開發人員用的上面說的就是,是在JVM啟動時創建;非堆是留給JVM自己用的,用來存放類的信息的。它和堆不同,運行期內GC不會釋放空間。如果web app用了大量的第三方jar或者應用有太多的class文件而恰好MaxPermSize設置較小,超出了也會導致這塊內存的佔用過多造成溢出,或者tomcat熱部署時侯不會清理前面載入的環境,只會將context更改為新部署的,非堆存的內容就會越來越多。
PermGen space的全稱是Permanent Generation space,是指內存的永久保存區域,這塊內存主要是被JVM存放Class和Meta信息的,Class在被Loader時就會被放到PermGen space中,它和存放類實例(Instance)的Heap區域不同,GC(Garbage Collection)不會在主程序運行期對PermGen space進行清理,所以如果你的應用中有很CLASS的話,就很可能出現PermGen space錯誤,這種錯誤常見在web伺服器對JSP進行pre compile的時候。如果你的WEB APP下都用了大量的第三方jar, 其大小超過了jvm默認的大小(4M)那麼就會產生此錯誤信息了。
一個最佳的配置例子:(經過本人驗證,自從用此配置之後,再未出現過tomcat死掉的情況)
set JAVA_OPTS=-Xms800m -Xmx800m -XX:PermSize=128M -XX:MaxNewSize=256m -XX:MaxPermSize=256m
2、java.lang.OutOfMemoryError: Javaheap space
第一種情況是個補充,主要存在問題就是出現在這個情況中。其默認空間(即-Xms)是物理內存的1/64,最大空間(-Xmx)是物理內存的1/4。如果內存剩餘不到40%,JVM就會增大堆到Xmx設置的值,內存剩餘超過70%,JVM就會減小堆到Xms設置的值。所以伺服器的Xmx和Xms設置一般應該設置相同避免每次GC後都要調整虛擬機堆的大小。假設物理內存無限大,那麼JVM內存的最大值跟操作系統有關,一般32位機是1.5g到3g之間,而64位的就不會有限制了。
注意:如果Xms超過了Xmx值,或者堆最大值和非堆最大值的總和超過了物理內存或者操作系統的最大限制都會引起伺服器啟動不起來。
垃圾回收GC的角色
JVM調用GC的頻度還是很高的,主要兩種情況下進行垃圾回收:
當應用程序線程空閑;另一個是java內存堆不足時,會不斷調用GC,若連續回收都解決不了內存堆不足的問題時,就會報out of memory錯誤。因為這個異常根據系統運行環境決定,所以無法預期它何時出現。
根據GC的機制,程序的運行會引起系統運行環境的變化,增加GC的觸發機會。
為了避免這些問題,程序的設計和編寫就應避免垃圾對象的內存佔用和GC的開銷。顯示調用System.GC()只能建議JVM需要在內存中對垃圾對象進行回收,但不是必須馬上回收,
一個是並不能解決內存資源耗空的局面,另外也會增加GC的消耗。
二、JVM內存區域組成
簡單的說java中的堆和棧
java把內存分兩種:一種是棧內存,另一種是堆內存
1、在函數中定義的基本類型變數和對象的引用變數都在函數的棧內存中分配;
2、堆內存用來存放由new創建的對象和數組
在函數(代碼塊)中定義一個變數時,java就在棧中為這個變數分配內存空間,當超過變數的作用域後,java會自動釋放掉為該變數所分配的內存空間;在堆中分配的內存由java虛擬機的自動垃圾回收器來管理
堆的優勢是可以動態分配內存大小,生存期也不必事先告訴編譯器,因為它是在運行時動態分配內存的。缺點就是要在運行時動態分配內存,存取速度較慢;
棧的優勢是存取速度比堆要快,缺點是存在棧中的數據大小與生存期必須是確定的無靈活性。
java堆分為三個區:New、Old和Permanent
GC有兩個線程:
新創建的對象被分配到New區,當該區被填滿時會被GC輔助線程移到Old區,當Old區也填滿了會觸發GC主線程遍歷堆內存里的所有對象。Old區的大小等於Xmx減去-Xmn
java棧存放
棧調整:參數有+UseDefaultStackSize -Xss256K,表示每個線程可申請256k的棧空間
每個線程都有他自己的Stack
三、JVM如何設置虛擬內存
提示:在JVM中如果98%的時間是用於GC且可用的Heap size 不足2%的時候將拋出此異常信息。
提示:Heap Size 最大不要超過可用物理內存的80%,一般的要將-Xms和-Xmx選項設置為相同,而-Xmn為1/4的-Xmx值。
提示:JVM初始分配的內存由-Xms指定,默認是物理內存的1/64;JVM最大分配的內存由-Xmx指定,默認是物理內存的1/4。
默認空餘堆內存小於40%時,JVM就會增大堆直到-Xmx的最大限制;空餘堆內存大於70%時,JVM會減少堆直到-Xms的最小限制。因此伺服器一般設置-Xms、-Xmx相等以避免在每次GC 後調整堆的大小。
提示:假設物理內存無限大的話,JVM內存的最大值跟操作系統有很大的關系。
簡單的說就32位處理器雖然可控內存空間有4GB,但是具體的操作系統會給一個限制,
這個限制一般是2GB-3GB(一般來說Windows系統下為1.5G-2G,linux系統下為2G-3G),而64bit以上的處理器就不會有限制了
提示:注意:如果Xms超過了Xmx值,或者堆最大值和非堆最大值的總和超過了物理內存或者操作系統的最大限制都會引起伺服器啟動不起來。
提示:設置NewSize、MaxNewSize相等,"new"的大小最好不要大於"old"的一半,原因是old區如果不夠大會頻繁的觸發"主" GC ,大大降低了性能
JVM使用-XX:PermSize設置非堆內存初始值,默認是物理內存的1/64;
由XX:MaxPermSize設置最大非堆內存的大小,默認是物理內存的1/4。
解決方法:手動設置Heap size
修改TOMCAT_HOME/bin/catalina.bat
在「echo "Using CATALINA_BASE: $CATALINA_BASE"」上面加入以下行:
JAVA_OPTS="-server -Xms800m -Xmx800m -XX:MaxNewSize=256m"
四、性能檢查工具使用
定位內存泄漏:
JProfiler工具主要用於檢查和跟蹤系統(限於Java開發的)的性能。JProfiler可以通過時時的監控系統的內存使用情況,隨時監視垃圾回收,線程運行狀況等手段,從而很好的監視JVM運行情況及其性能。
1. 應用伺服器內存長期不合理佔用,內存經常處於高位佔用,很難回收到低位
② jprofiler 9.2 怎麼使用
:打開 菜單Session->Integeration Widzards ->new Server Integeration 第二步:選擇 Generic Application Server->On a remote computer 第三步:JVM選擇建議選擇Oracle,根據實際情況選擇Version和Mode。Mode選擇使用的是interpreted。 第四步:選擇wait for a connection from the Jprofiler GUI,點擊next 第五步:Remote地址填寫要連接的Linux下的IP:比如192.168.51.132 第六步:填寫Linux下jprofiler的安裝目錄:如圖所示 第七步:埠使用jprofiler默認的8849 後面的步驟點到Finish即可。
③ jprofiler 9.2 windows和linux的jdk可以不相同嗎
Java™堆耗盡並不是造成java.lang.OutOfMemoryError的惟一原因。如果本機內存耗盡,則會發生普通調試技巧無法解決的OutOfMemoryError。本文將討論本機內存的概念,Java運行時如何使用它,它被耗盡時會出現什麼情況,以及如何在Windows®和Linux®上調試本機OutOfMemoryError。針對AIX®系統的相同主題將在另一篇同類文章中介紹。Java堆(每個Java對象在其中分配)是您在編寫Java應用程序時使用最頻繁的內存區域。JVM設計用於將我們與主機的特性隔離,所以將內存當作堆來考慮再正常不過了。您一定遇到過Java堆OutOfMemoryError,它可能是由於對象泄漏造成的,也可能是因為堆的大小不足以存儲所有數據,您也可能了解這些場景的一些調試技巧。但是隨著您的Java應用程序處理越來越多的數據和越來越多的並發負載,您可能就會遇到無法使用常規技巧進行修復的OutOfMemoryError。在一些場景中,即使java堆未滿,也會拋出錯誤。當這類場景發生時,您需要理解Java運行時環境(JavaRuntimeEnvironment,JRE)內部到底發生了什麼。Java應用程序在Java運行時的虛擬化環境中運行,但是運行時本身是使用C之類的語言編寫的本機程序,它也會耗用本機資源,包括本機內存。本機內存是可用於運行時進程的內存,它與Java應用程序使用的java堆內存不同。每種虛擬化資源(包括Java堆和Java線程)都必須存儲在本機內存中,虛擬機在運行時使用的數據也是如此。這意味著主機的硬體和操作系統施加在本機內存上的限制會影響到Java應用程序的性能。本系列文章共分兩篇,討論不同平台上的相應話題。本文是其中一篇。在這兩篇文章中,您將了解什麼是本機內存,Java運行時如何使用它,本機內存耗盡之後會發生什麼情況,以及如何調試本機OutOfMemoryError。本文介紹Windows和Linux平台上的這一主題,不會介紹任何特定的運行時實現。另一篇類似的文章介紹AIX上的這一主題,著重介紹IBM®DeveloperKitforJava。(另一篇文章中關於IBM實現的信息也適合於除AIX之外的平台,因此如果您在Linux上使用IBMDeveloperKitforJava,或使用IBM32-,您會發現這篇文章也有用處)。本機內存簡介我將首先解釋一下操作系統和底層硬體給本機內存帶來的限制。如果您熟悉使用C等語言管理動態內存,那麼您可以直接跳到下一節。硬體限制本機進程遇到的許多限制都是由硬體造成的,而與操作系統沒有關系。每台計算機都有一個處理器和一些隨機存取存儲器(RAM),後者也稱為物理內存。處理器將數據流解釋為要執行的指令,它擁有一個或多個處理單元,用於執行整數和浮點運算以及更高級的計算。處理器具有許多寄存器——常快速的內存元素,用作被執行的計算的工作存儲,寄存器大小決定了一次計算可使用的最大數值。處理器通過內存匯流排連接到物理內存。物理地址(處理器用於索引物理RAM的地址)的大小限制了可以定址的內存。例如,一個16位物理地址可以定址0x0000到0xFFFF的內存地址,這個地址范圍包括2^16=65536個惟一的內存位置。如果每個地址引用一個存儲位元組,那麼一個16位物理地址將允許處理器定址64KB內存。處理器被描述為特定數量的數據位。這通常指的是寄存器大小,但是也存在例外,比如32位390指的是物理地址大小。對於桌面和伺服器平台,這個數字為31、32或64;對於嵌入式設備和微處理器,這個數字可能小至4。物理地址大小可以與寄存器帶寬一樣大,也可以比它大或小。如果在適當的操作系統上運行,大部分64位處理器可以運行32位程序。表1列出了一些流行的Linux和Windows架構,以及它們的寄存器和物理地址大小:表1.一些流行處理器架構的寄存器和物理地址大小架構寄存器帶寬(位)物理地址大小(位)(現代)Intel®x86323236,具有物理地址擴展(PentiumPro和更高型號)x866464目前為48位(以後將會增大)PPC6464在POWER5上為50位39031位323139064位6464操作系統和虛擬內存如果您編寫無需操作系統,直接在處理器上運行的應用程序,您可以使用處理器可以定址的所有內存(假設連接到了足夠的物理RAM)。但是要使用多任務和硬體抽象等特性,幾乎所有人都會使用某種類型的操作系統來運行他們的程序。在Windows和Linux等多任務操作系統中,有多個程序在使用系統資源。需要為每個程序分配物理內存區域來在其中運行。可以設計這樣一個操作系統:每個程序直接使用物理內存,並且可以可靠地僅使用分配給它的內存。一些嵌入式操作系統以這種方式工作,但是這在包含多個未經過集中測試的應用程序的環境中是不切實際的,因為任何程序都可能破壞其他程序或者操作系統本身的內存。虛擬內存允許多個進程共享物理內存,而且不會破壞彼此的數據。在具有虛擬內存的操作系統(比如Windows、Linux和許多其他操作系統)中,每個程序都擁有自己的虛擬地址空間——一個邏輯地址區域,其大小由該系統上的地址大小規定(所以,桌面和伺服器平台的虛擬地址空間為31、32或64位)。進程的虛擬地址空間中的區域可被映射到物理內存、文件或任何其他可定址存儲。當數據未使用時,操作系統可以在物理內存與一個交換區域(Windows上的頁面文件或者Linux上的交換分區)之間移動它,以實現對物理內存的最佳利用率。當一個程序嘗試使用虛擬地址訪問內存時,操作系統連同片上硬體會將該虛擬地址映射到物理位置,這個位置可以是物理RAM、一個文件或頁面文件/交換分區。如果一個內存區域被移動到交換空間,那麼它將在被使用之前載入回物理內存中。圖1展示了虛擬內存如何將進程地址空間區域映射到共享資源:程序的每個實例以進程的形式運行。在Linux和Windows上,進程是一個由受操作系統控制的資源(比如文件和套接字信息)、一個典型的虛擬地址空間(在某些架構上不止一個)和至少一個執行線程構成的集合。虛擬地址空間大小可能比處理器的物理地址大小更小。32位Intelx86最初擁有的32位物理地址僅允許處理器定址4GB存儲空間。後來,添加了一種稱為物理地址擴展(PhysicalAddressExtension,PAE)的特性,將物理地址大小擴大到了36位,允許安裝或定址至多64GBRAM。PAE允許操作系統將32位的4GB虛擬地址空間映射到一個較大的物理地址范圍,但是它不允許每個進程擁有64GB虛擬地址空間。這意味著如果您將大於4GB的內存放入32位Intel伺服器中,您將無法將所有內存直接映射到一個單一進程中。地址窗口擴展(AddressWindowingExtension)特性允許Windows進程將其32位地址空間的一部分作為滑動窗口映射到較大的內存區域中。Linux使用類似的技術將內存區域映射到虛擬地址空間中。這意味著盡管您無法直接引用大於4GB的內存,但您仍然可以使用較大的內存區域。內核空間和用戶空間盡管每個進程都有其自己的地址空間,但程序通常無法使用所有這些空間。地址空間被劃分為用戶空間和內核空間。內核是主要的操作系統程序,包含用於連接計算機硬體、調度程序以及提供聯網和虛擬內存等服務的邏輯。作為計算機啟動序列的一部分,操作系統內核運行並初始化硬體。一旦內核配置了硬體及其自己的內部狀態,第一個用戶空間進程就會啟動。如果用戶程序需要來自操作系統的服務,它可以執行一種稱為系統調用的操作與內核程序交互,內核程序然後執行該請求。系統調用通常是讀取和寫入文件、聯網和啟動新進程等操作所必需的。當執行系統調用時,內核需要訪問其自己的內存和調用進程的內存。因為正在執行當前線程的處理器被配置為使用地址空間映射來為當前進程映射虛擬地址,所以大部分操作系統將每個進程地址空間的一部分映射到一個通用的內核內存區域。被映射來供內核使用的地址空間部分稱為內核空間,其餘部分稱為用戶空間,可供用戶應用程序使用。內核空間和用戶空間之間的平衡關系因操作系統的不同而不同,甚至在運行於不同硬體架構之上的同一操作系統的各個實例間也有所不同。這種平衡通常是可配置的,可進行調整來為用戶應用程序或內核提供空間。縮減內核區域可能導致一些問題,比如能夠同時登錄的用戶數量限制或能夠運行的進程數量限制。更小的用戶空間意味著應用程序編程人員只能使用更少的內存空間。默認情況下,32位Windows擁有2GB用戶空間和2GB內核空間。在一些Windows版本上,通過向啟動配置添加/3GB開關並使用/LARGEADDRESSAWARE開關重新鏈接應用程序,可以將這種平衡調整為3GB用戶空間和1GB內核空間。在32位Linux上,默認設置為3GB用戶空間和1GB內核空間。一些Linux分發版提供了一個hugemem內核,支持4GB用戶空間。為了實現這種配置,將進行系統調用時使用的地址空間分配給內核。通過這種方式增加用戶空間會減慢系統調用,因為每次進行系統調用時,操作系統必須在地址空間之間復制數據並重置進程地址-空間映射。圖2展示了32位Windows的地址-空間布局:31位Linux390上還使用了一個獨立的內核地址空間,其中較小的2GB地址空間使對單個地址空間進行劃分不太合理,但是,390架構可以同時使用多個地址空間,而且不會降低性能。進程空間必須包含程序需要的所有內容,包括程序本身和它使用的共享庫(在Windows上為DDL,在Linux上為.so文件)。共享庫不僅會占據空間,使程序無法在其中存儲數據,它們還會使地址空間碎片化,減少可作為連續內存塊分配的內存。這對於在擁有3GB用戶空間的Windowsx86上運行的程序尤為明顯。DLL在構建時設置了首選的載入地址:當載入DLL時,它被映射到處於特定位置的地址空間,除非該位置已經被佔用,在這種情況下,它會載入到別處。WindowsNT最初設計時設置了2GB可用用戶空間,這對於要構建來載入接近2GB區域的系統庫很有用——使大部分用戶區域都可供應用程序自由使用。當用戶區域擴展到3GB時,系統共享庫仍然載入接近2GB數據(約為用戶空間的一半)。盡管總體用戶空間為3GB,但是不可能分配3GB大的內存塊,因為共享庫無法載入這么大的內存。在Windows中使用/3GB開關,可以將內核空間減少一半,也就是最初設計的大小。在一些情形下,可能耗盡1GB內核空間,使I/O變得緩慢,且無法正常創建新的用戶會話。盡管/3GB開關可能對一些應用程序非常有用,但任何使用它的環境在部署之前都應該進行徹底的負載測試。參見參考資料,獲取關於/3GB開關及其優缺點的信息的鏈接。本機內存泄漏或過度使用本機內存將導致不同的問題,具體取決於您是耗盡了地址空間還是用完了物理內存。耗盡地址空間通常只會發生在32位進程上,因為最大4GB的內存很容易分配完。64位進程具有數百或數千GB的用戶空間,即使您特意消耗空間也很難耗盡這么大的空間。如果您確實耗盡了Java進程的地址空間,那麼Java運行時可能會出現一些陌生現象,本文稍後將詳細討論。當在進程地址空間比物理內存大的系統上運行時,內存泄漏或過度使用本機內存會迫使操作系統交換後備存儲器來用作本機進程的虛擬地址空間。訪問經過交換的內存地址比讀取駐留(在物理內存中)的地址慢得多,因為操作系統必須從硬碟驅動器拉取數據。可能會分配大量內存來用完所有物理內存和所有交換內存(頁面空間),在Linux上,這將觸發內核內存不足(OOM)結束程序,強制結束最消耗內存的進程。在Windows上,與地址空間被占滿時一樣,內存分配將會失敗。同時,如果嘗試使用比物理內存大的虛擬內存,顯然在進程由於消耗內存太大而被結束之前就會遇到問題。系統將變得異常緩慢,因為它會將大部分時間用於在內存與交換空間之間來回復制數據。當發生這種情況時,計算機和獨立應用程序的性能將變得非常糟糕,從而使用戶意識到出現了問題。當JVM的Java堆被交換出來時,垃圾收集器的性能會變得非常差,應用程序可能被掛起。如果一台機器上同時使用了多個Java運行時,那麼物理內存必須足夠分配給所有Java堆。Java運行時如何使用本機內存Java運行時是一個操作系統進程,它會受到我在上一節中列出的硬體和操作系統局限性的限制。運行時環境提供的功能受一些未知的用戶代碼驅動,這使得無法預測在每種情形中運行時環境將需要何種資源。Java應用程序在託管Java環境中執行的每個操作都會潛在地影響提供該環境的運行時的需求。本節描述Java應用程序為什麼和如何使用本機內存。Java堆和垃圾收集Java堆是分配了對象的內存區域。大多數JavaSE實現都擁有一個邏輯堆,但是一些專家級Java運行時擁有多個堆,比如實現Java實時規范(RealTimeSpecificationforJava,RTSJ)的運行時。一個物理堆可被劃分為多個邏輯扇區,具體取決於用於管理堆內存的垃圾收集(GC)演算法。這些扇區通常實現為連續的本機內存塊,這些內存塊受Java內存管理器(包含垃圾收集器)控制。堆的大小可以在Java命令行使用-Xmx和-Xms選項來控制(mx表示堆的最大大小,ms表示初始大小)。盡管邏輯堆(經常被使用的內存區域)可以根據堆上的對象數量和在GC上花費的時間而增大和縮小,但使用的本機內存大小保持不變,而且由-Xmx值(最大堆大小)指定。大部分GC演算法依賴於被分配為連續的內存塊的堆,因此不能在堆需要擴大時分配本機內存。所有堆內存必須預先保留。保留本機內存與分配本機內存不同。當本機內存被保留時,無法使用物理內存或其他存儲器作為備用內存。盡管保留地址空間塊不會耗盡物理資源,但會阻止內存被用於其他用途。由保留從未使用的內存導致的泄漏與泄漏分配的內存一樣嚴重。當使用的堆區域縮小時,一些垃圾收集器會回收堆的一部分(釋放堆的後備存儲空間),從而減少使用的物理內存。對於維護Java堆的內存管理系統,需要本機內存來維護它的狀態。當進行垃圾收集時,必須分配數據結構來跟蹤空閑存儲空間和記錄進度。這些數據結構的確切大小和性質因實現的不同而不同,但許多數據結構都與堆大小成正比。即時(JIT)編譯器JIT編譯器在運行時編譯Java位元組碼來優化本機可執行代碼。這極大地提高了Java運行時的速度,並且支持Java應用程序以與本機代碼相當的速度運行。位元組碼編譯使用本機內存(使用方式與gcc等靜態編譯器使用內存來運行一樣),但JIT編譯器的輸入(位元組碼)和輸出(可執行代碼)必須也存儲在本機內存中。包含多個經過JIT編譯的方法的Java應用程序會使用比小型應用程序的本機內存。類和類載入器Java應用程序由一些類組成,這些類定義對象結構和方法邏輯。Java應用程序也使用Java運行時類庫(比如java.lang.String)中的類,也可以使用第三方庫。這些類需要存儲在內存中以備使用。存儲類的方式取決於具體實現。SunJDK使用永久生成(permanentgeneration,PermGen)堆區域。Java5的IBM實現會為每個類載入器分配本機內存塊,並將類數據存儲在其中。現代Java運行時擁有類共享等技術,這些技術可能需要將共享內存區域映射到地址空間。要理解這些分配機制如何影響您Java運行時的本機內存佔用,您需要查閱該實現的技術文檔。然而,一些普遍的事實會影響所有實現。從最基本的層面來看,使用的類將需要使用內存。(這可能意味著您的本機內存使用量會增加,或者您必須明確地重新設置PermGen或共享類緩存等區域的大小,以裝入所有類)。記住,不僅您的應用程序需要載入到內存中,框架、應用伺服器、第三方庫以及包含類的Java運行時也會按需載入並佔用空間。Java運行時可以卸載類來回收空間,但是只有在非常嚴酷的條件下才會這樣做。不能卸載單個類,而是卸載類載入器,隨其載入的所有類都會被卸載。只有在以下情況下才能卸載類載入器:Java堆不包含對表示該類載入器的java.lang.ClassLoader對象的引用。Java堆不包含對表示類載入器載入的類的任何java.lang.Class對象的引用。在Java堆上,該類載入器載入的任何類的所有對象都不再存活(被引用)。需要注意的是,Java運行時為所有Java應用程序創建的3個默認類載入器(bootstrap、extension和application)都不可能滿足這些條件,因此,任何系統類(比如java.lang.String)或通過應用程序類載入器載入的任何應用程序類都不能在運行時釋放。即使類載入器適合進行收集,運行時也只會將收集類載入器作為GC周期的一部分。一些實現只會在某些GC周期中卸載類載入器。也可能在運行時生成類,而不用釋放它。許多JEE應用程序使用JavaServerPages(JSP)技術來生成Web頁面。使用JSP會為執行的每個.jsp頁面生成一個類,並且這些類會在載入它們的類載入器的整個生存期中一直存在——這個生存期通常是Web應用程序的生存期。另一種生成類的常見方法是使用Java反射。反射的工作方式因Java實現的不同而不同,但Sun和IBM實現都使用了這種方法,我馬上就會講到。當使用java.lang.reflectAPI時,Java運行時必須將一個反射對象(比如java.lang.reflect.Field)的方法連接到被反射到的對象或類。這可以通過使用Java本機介面(JavaNativeInterface,JNI)訪問器來完成,這種方法需要的設置很少,但是速度緩慢。也可以在運行時為您想要反射到的每種對象類型動態構建一個類。後一種方法在設置上更慢,但運行速度更快,非常適合於經常反射到一個特定類的應用程序。Java運行時在最初幾次反射到一個類時使用JNI方法,但當使用了若干次JNI方法之後,訪問器會膨脹為位元組碼訪問器,這涉及到構建類並通過新的類載入器進行載入。執行多次反射可能導致創建了許多訪問器類和類載入器。保持對反射對象的引用會導致這些類一直存活,並繼續佔用空間。因為創建位元組碼訪問器非常緩慢,所以Java運行時可以緩存這些訪問器以備以後使用。一些應用程序和框架還會緩存反射對象,這進一步增加了它們的本機內存佔用。JNIJNI支持本機代碼(使用C和C++等本機編譯語言編寫的應用程序)調用Java方法,反之亦然。Java運行時本身極大地依賴於JNI代碼來實現類庫功能,比如文件和網路I/O。JNI應用程序可能通過3種方式增加Java運行時的本機內存佔用:JNI應用程序的本機代碼被編譯到共享庫中,或編譯為載入到進程地址空間中的可執行文件。大型本機應用程序可能僅僅載入就會佔用大量進程地址空間。本機代碼必須與Java運行時共享地址空間。任何本機代碼分配或本機代碼執行的內存映射都會耗用Java運行時的內存。某些JNI函數可能在它們的常規操作中使用本機內存。GetTypeArrayElements和GetTypeArrayRegion函數可以將Java堆數據復制到本機內存緩沖區中,以供本機代碼使用。是否復制數據依賴於運行時實現。(IBMDeveloperKitforJava5.0和更高版本會進行本機復制)。通過這種方式訪問大量Java堆數據可能會使用大量本機堆。
④ 如何優化java虛擬機,提高性能
關於性能調優:
1 需要一個性能探測器,找到調用最頻繁的代碼段,優化這部分代碼(優化演算法)
2 往往1%的代碼運行時間佔99%。所以優化這些代碼就能事半功倍。
3 最好是能看懂編譯後的代碼,這樣分析最徹底。
Java的性能分析使用JProfiler
堆棧分析使用的Jstack
Java性能調優 SSH框架優化以適應特定的項目
一、JVM調優
1 各種垃圾回收演算法及其優劣;
2 針對不同應用類型如何選擇JVM參數
3 常用調優工具的使用(jps/jstat/jmap/jstack/jinfo/jhat)
4 調優案例分析(如何選擇不同內存塊的大小,如何選擇不同的演算法來提升性能、響應時間)
二、Java應用中CPU佔用率、使用情況分析,線程死鎖等鎖
系統性能瓶頸的分析定位
1 JStack的深度使用
2 各種Linux監控命令的配合使用(top,vmstat,iostat,sar 不要輕信自己能完全掌控這些命令)、分析
(前一陣Java漏洞通過製造Hash沖突來占盡CPU資源就可以通過top命令快速定位到,你肯定沒有這么用過)
3 JProfiler的詳細使用
三、Java內存溢出分析
1 用EMA來分析內存佔用情況
2 通過案例分析來定位內存泄漏
互聯網中的性能主要是兩個方面:
1 吞吐量,就是系統支持的訪問量。
2 延遲,就是一個請求提交後,相應的時間。
一般硬體不變的情況下,兩方面各自優化到極限後,相互會制約,也就是吞吐量增強的話比如需要延遲加大,反之亦然。
⑤ 如何在linux下檢測內存泄漏
內存泄漏指由於疏忽或錯誤造成程序未能釋放已經不再使用的內存的情況。內存泄漏並非指內存在物理上的消失,而是應用程序分配某段內存後,由於設計錯誤,失去了對該段內存的控制,因而造成了內存的浪費。
可以使用相應的軟體測試工具對軟體進行檢測。
1. ccmalloc-Linux和Solaris下對C和C++程序的簡單的使用內存泄漏和malloc調試庫。
2. Dmalloc-Debug Malloc Library.
3. Electric
Fence-Linux分發版中由Bruce Perens編寫的malloc()調試庫。
4. Leaky-Linux下檢測內存泄漏的程序。
5. LeakTracer-Linux、Solaris和HP-UX下跟蹤和分析C++程序中的內存泄漏。
6. MEMWATCH-由Johan
Lindh編寫,是一個開放源代碼C語言內存錯誤檢測工具,主要是通過gcc的precessor來進行。
7. Valgrind-Debugging and profiling Linux programs, aiming at
programs written in C and C++.
8. KCachegrind-A visualization tool for the profiling data
generated by Cachegrind and Calltree.
9. Leak
Monitor-一個Firefox擴展,能找出跟Firefox相關的泄漏類型。
10. IE Leak Detector
(Drip/IE Sieve)-Drip和IE Sieve leak
detectors幫助網頁開發員提升動態網頁性能通過報告可避免的因為IE局限的內存泄漏。
11. Windows Leaks
Detector-探測任何Win32應用程序中的任何資源泄漏(內存,句柄等),基於Win API調用鉤子。
12. SAP Memory
Analyzer-是一款開源的JAVA內存分析軟體,可用於輔助查找JAVA程序的內存泄漏,能容易找到大塊內存並驗證誰在一直佔用它,它是基於Eclipse
RCP(Rich Client Platform),可以下載RCP的獨立版本或者Eclipse的插件。
13. DTrace-即動態跟蹤Dynamic
Tracing,是一款開源軟體,能在Unix類似平台運行,用戶能夠動態檢測操作系統內核和用戶進程,以更精確地掌握系統的資源使用狀況,提高系統性能,減少支持成本,並進行有效的調節。
14. IBM Rational PurifyPlus-幫助開發人員查明C/C++、託管.NET、Java和VB6代碼中的性能和可靠性錯誤。PurifyPlus
將內存錯誤和泄漏檢測、應用程序性能描述、代碼覆蓋分析等功能組合在一個單一、完整的工具包中。
15. Parasoft Insure++-針對C/C++應用的運行時錯誤自動檢測工具,它能夠自動監測C/C++程序,發現其中存在著的內存破壞、內存泄漏、指針錯誤和I/O等錯誤。並通過使用一系列獨特的技術(SCI技術和變異測試等),徹底的檢查和測試我們的代碼,精確定位錯誤的准確位置並給出詳細的診斷信息。能作為Microsoft
Visual C++的一個插件運行。
16. Compuware DevPartner for Visual C++ BoundsChecker
Suite-為C++開發者設計的運行錯誤檢測和調試工具軟體。作為Microsoft Visual Studio和C++ 6.0的一個插件運行。
17. Electric Software GlowCode-包括內存泄漏檢查,code
profiler,函數調用跟蹤等功能。給C++和.Net開發者提供完整的錯誤診斷,和運行時性能分析工具包。
18. Compuware DevPartner Java
Edition-包含Java內存檢測,代碼覆蓋率測試,代碼性能測試,線程死鎖,分布式應用等幾大功能模塊。
19. Quest JProbe-分析Java的內存泄漏。
20. ej-technologies JProfiler-一個全功能的Java剖析工具,專用於分析J2SE和J2EE應用程序。它把CPU、執行緒和內存的剖析組合在一個強大的應用中。JProfiler可提供許多IDE整合和應用伺服器整合用途。JProfiler直覺式的GUI讓你可以找到效能瓶頸、抓出內存泄漏、並解決執行緒的問題。4.3.2注冊碼:A-G666#76114F-1olm9mv1i5uuly#0126
21. BEA JRockit-用來診斷Java內存泄漏並指出根本原因,專門針對Intel平台並得到優化,能在Intel硬體上獲得最高的性能。
22. SciTech Software AB .NET Memory
Profiler-找到內存泄漏並優化內存使用針對C#,VB.Net,或其它.Net程序。
23. YourKit .NET & Java Profiler-業界領先的Java和.NET程序性能分析工具。
24. AutomatedQA AQTime-AutomatedQA的獲獎產品performance profiling和memory
debugging工具集的下一代替換產品,支持Microsoft, Borland, Intel, Compaq 和
GNU編譯器。可以為.NET和Windows程序生成全面細致的報告,從而幫助您輕松隔離並排除代碼中含有的性能問題和內存/資源泄露問題。支持.Net
1.0,1.1,2.0,3.0和Windows 32/64位應用程序。
25. JavaScript Memory Leak Detector-微軟全球產品開發歐洲團隊(Global Proct
Development- Europe team, GPDE)
發布的一款調試工具,用來探測JavaScript代碼中的內存泄漏,運行為IE系列的一個插件。
⑥ 如何使用JProfiler查找內存泄漏
先運行的java程序,然後打開jprofiler,綁定正在運行的程序,就可以在界面看到內存的使用情況。
⑦ 請問什麼叫java內存泄露
上面的已經介紹得很清楚了,簡單點說就是java沒有釋放用過的內存,繼續在系統內存中佔用!