Java 堆内存优化
????Java 堆的唯一目的就是創建實例對象,幾乎所有的對象都在堆上分配內存,如果堆空間分配內存出現問題可見是非常嚴重的。當 Java 堆內存出現問題時,我們應該怎么去優化呢?在學習堆內存優化之前,我們要先了解一下有關堆內存優化的參數。堆在實現時,既可以實現成固定大小的,也可以是可擴展的,當前主流的虛擬機都是按照可擴展來實現的(通過-Xmx 和-Xms 控制)。
????在這里通過程序測試一下:
public class HeapTest {public static void main(String[] args) {long maxMemory = Runtime.getRuntime().maxMemory() ; //返回 Java 虛擬機試圖使用的最大內存量。long totalMemory = Runtime.getRuntime().totalMemory() ; //返回 Java 虛擬機中的內存總量。System.out.println("最大分配內存 = " + maxMemory + "(字節)、" + (maxMemory / (double)1024 / 1024) + " MB");System.out.println("初始化分配內存大小 = " + totalMemory + "(字節)、" + (totalMemory / (double)1024 / 1024) + " MB");}} 輸出:
最大分配內存 = 1883242496(字節)、1796.0 MB
初始化分配內存大小 = 128974848(字節)、123.0 MB
????博主的電腦是 8G 的內存大小,可見在默認的情況下默認的:堆分配的內存是總內存的“1 / 4”、而初始化的內存為“1 / 64”。接下來我們也看一下運行程序時輸出的 GC 信息日志,我們右鍵 Run As->Run Configuratios 會出現這樣的一個對話框,我們在紅線區域輸入我們要設置的堆最大分配內存與初始化內存大小,這里都設置了 1G 大小的內存。
????我們點擊 Run,下面是輸出的結果:從下面的圖可以看出,Heap 下有三個內存空間 PSYoungGen (新生代)、ParOldGen(老年代)、Metaspace(元空間),由于我們設置了堆的初始化大小,從輸出結果可以看出為 981.5 MB 大小。 但是經過計算 PSYoungGen 與 ParOldGen 就占據了所有了初始化堆內存空間,那 Metaspace 在哪里呢?其實在 Java 8 之前是不存在 Metaspace 的,在 Java 8 中永久代被移除了方法區,為了替代永久代于是 Metaspace 誕生了,但是它和之前的永久代的保存的數據并不完全一樣。Java 運行時數據區域介紹傳送~ 博主使用的是 jdk1.8,如果是 jdk1.7 以前的版本那么就不會看到 Metaspace 而是 PSPermGen(永久代),當然這也可以證明在 jdk1.8 中永久代已經被移除了。方法區是堆的一個邏輯部分,但是它卻有一個別名叫做 Non-Heap(非堆),也就是說它并不是堆內存空間。這也難怪為什么 PSYoungGen 和 ParOldGen 的內存總和就占據了所有的堆內存初始化空間。
????下面我們就來看一下堆內存溢出的情況:這里我創建了一個集合并不斷的創建新對象添加到集合中去。
import java.util.ArrayList; import java.util.List;public class TestOutOfMemoryError {public static void main(String[] args) {List<Test> list = new ArrayList<>();while(true){list.add(new Test());}} }class Test{}????然后不一會就出現了這樣的情況:報了一個 OutOfMemoryError 的異常,這個異常告訴我們堆內存已經溢出了,你寫的程序有問題 (如果有的同學也寫了這樣一段代碼,結果很久也沒報異常,不是不會報異常,只是堆內存還沒有溢出,你只需要慢慢等就好啦,其實博主在運行之前就偷偷將參數都設置成了 1m 大小…….)。
????但是我們只知道是內存溢出了,但是哪里溢出了?我們不能夠通過該異常分析出異常出現的地方,這時我們可以使用 -XX:+HeapDumpOnOutOfMemoryError 參數導出一個.hprof 文件然后分析該文件快速定位到內存泄漏的地方。
導出該文件需要安裝一個插件,博主使用的 eclipse ,可以從 eclipse 的官網上復制一個鏈接 http://download.eclipse.org/mat/1.7/update-site/,按照下面的操作在 eclipse 安裝該插件即可。
????下面我們就來看一下該文件都是有些什么?運行以后刷新我們的工程。
????刷新工程以后就會發現我們的項目下多了一個類似于 java_pid6504.hprof 的文件。在博主的 eclipse 下打開是一堆亂碼,于是需要下載一個解析該文件的軟件 MemoryAnalyzer,直接在百度上搜索即可。
????用 MemoryAnalyzer 打開該文件,發現打開該文件后是這個樣子的,然后就可以愉快的知道堆創建對象的過程了。
總結
以上是生活随笔為你收集整理的Java 堆内存优化的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 电脑重启关不了机怎么办啊 电脑无法正常关
- 下一篇: 电脑无法检测u盘怎么办 U盘无法被电脑检