1. 程式人生 > >jvm基礎知識1

jvm基礎知識1

關系 fff catch pri 控制 jvm path 清除 command

技術分享

技術分享

技術分享

技術分享

堆放實例對象,棧放實例對象的引用,方法區存儲創建類的信息

技術分享

上面堆和垃圾回收的關系,垃圾回收回收的是堆內存的數據,s0和s1區域,

例如現在我們要清除s0中的堆對象,將s0中正在運行的對象從s0區域移動到s1區域中,然後將s0中要被清除的堆對象清除,現在對象都存儲在s1中,s0中為空,即下來要清除s1中的對象,將不被清除的對象從s1中移動到s0中,將s1中的對象清除,依次類推

接下來學習下虛擬機的參數:

技術分享

1、第一點給堆設置參數

技術分享

-Xms5m -Xmx20m

初始化堆大小5m,最大設置為20M,-XX:+PrintCommandLineFlags將配置的參數從控制臺打印輸出

配置參數:

技術分享

技術分享

我們來看下面代碼的運行結果:

package com.bjsxt.base001;


public class Test01 {

    public static void main(String[] args) {

        //-Xms5m -Xmx20m -XX:+PrintGCDetails -XX:+UseSerialGC -XX:+PrintCommandLineFlags
        
        //查看GC信息
        System.out.println("max memory:" + Runtime.getRuntime().maxMemory());
        System.out.println(
"free memory:" + Runtime.getRuntime().freeMemory()); System.out.println("total memory:" + Runtime.getRuntime().totalMemory()); byte[] b1 = new byte[1*1024*1024]; System.out.println("分配了1M"); System.out.println("max memory:" + Runtime.getRuntime().maxMemory()); System.out.println(
"free memory:" + Runtime.getRuntime().freeMemory()); System.out.println("total memory:" + Runtime.getRuntime().totalMemory()); byte[] b2 = new byte[4*1024*1024]; System.out.println("分配了4M"); System.out.println("max memory:" + Runtime.getRuntime().maxMemory()); System.out.println("free memory:" + Runtime.getRuntime().freeMemory()); System.out.println("total memory:" + Runtime.getRuntime().totalMemory()); } }

-XX:InitialHeapSize=5242880 -XX:MaxHeapSize=20971520 -XX:+PrintCommandLineFlags -XX:+PrintGCDetails -XX:+UseCompressedOops -XX:-UseLargePagesIndividualAllocation -XX:+UseSerialGC
max memory:20316160
free memory:4418752
total memory:5111808
[GC[DefNew: 676K->127K(1536K), 0.0014042 secs] 676K->481K(4992K), 0.0014266 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
分配了1M
max memory:20316160
free memory:3541280
total memory:5111808
[GC[DefNew: 1180K->0K(1536K), 0.0010578 secs][Tenured: 1505K->1505K(3456K), 0.0022471 secs] 1533K->1505K(4992K), [Perm : 2511K->2511K(21248K)], 0.0033312 secs] [Times: user=0.02 sys=0.00, real=0.00 secs]
分配了4M
max memory:20316160
free memory:3625944
total memory:9441280
Heap
def new generation total 1664K, used 108K [0x00000000f9a00000, 0x00000000f9bc0000, 0x00000000fa0a0000)
eden space 1536K, 7% used [0x00000000f9a00000, 0x00000000f9a1b100, 0x00000000f9b80000)
from space 128K, 0% used [0x00000000f9b80000, 0x00000000f9b80000, 0x00000000f9ba0000)
to space 128K, 0% used [0x00000000f9ba0000, 0x00000000f9ba0000, 0x00000000f9bc0000)
tenured generation total 7556K, used 5601K [0x00000000fa0a0000, 0x00000000fa801000, 0x00000000fae00000)
the space 7556K, 74% used [0x00000000fa0a0000, 0x00000000fa618670, 0x00000000fa618800, 0x00000000fa801000)
compacting perm gen total 21248K, used 2520K [0x00000000fae00000, 0x00000000fc2c0000, 0x0000000100000000)
the space 21248K, 11% used [0x00000000fae00000, 0x00000000fb076370, 0x00000000fb076400, 0x00000000fc2c0000)
No shared spaces configured.

技術分享

[GC[DefNew: 1180K->0K(1536K), 0.0010578 secs][Tenured: 1505K->1505K(3456K), 0.0022471 secs] 1533K->1505K(4992K), [Perm : 2511K->2511K(21248K)], 0.0033312 secs] [Times: user=0.02 sys=0.00, real=0.00 secs]

表示進行了垃圾回收,DefNew表示回收了新生代,Tenured表示回收了老年代,Perm 表示回收了永久區

技術分享

新生代會頻繁被GC不穩定,新生代包含eden空間 s1 和s0空間

我們來看下面的列子:

package com.bjsxt.base001;

public class Test02 {

    public static void main(String[] args) {
        
        //第一次配置
        //-Xms20m -Xmx20m -Xmn1m -XX:SurvivorRatio=2 -XX:+PrintGCDetails -XX:+UseSerialGC
        
        //第二次配置
        //-Xms20m -Xmx20m -Xmn7m -XX:SurvivorRatio=2 -XX:+PrintGCDetails -XX:+UseSerialGC
        
        //第三次配置
        //-XX:NewRatio=老年代/新生代
        //-Xms20m -Xmx20m -XX:SurvivorRatio=2 -XX:+PrintGCDetails -XX:+UseSerialGC
        
        byte[] b = null;
        //連續向系統申請10MB空間
        for(int i = 0 ; i <10; i ++){
            b = new byte[1*1024*1024];
        }
    }
}

技術分享

程序運行的效果是:

[GC[DefNew: 512K->255K(768K), 0.0013618 secs] 512K->439K(20224K), 0.0013894 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
Heap
def new generation total 768K, used 428K [0x00000000f9a00000, 0x00000000f9b00000, 0x00000000f9b00000)
eden space 512K, 33% used [0x00000000f9a00000, 0x00000000f9a2b300, 0x00000000f9a80000)
from space 256K, 99% used [0x00000000f9ac0000, 0x00000000f9affff8, 0x00000000f9b00000)
to space 256K, 0% used [0x00000000f9a80000, 0x00000000f9a80000, 0x00000000f9ac0000)
tenured generation total 19456K, used 10424K [0x00000000f9b00000, 0x00000000fae00000, 0x00000000fae00000)
the space 19456K, 53% used [0x00000000f9b00000, 0x00000000fa52e040, 0x00000000fa52e200, 0x00000000fae00000)
compacting perm gen total 21248K, used 2517K [0x00000000fae00000, 0x00000000fc2c0000, 0x0000000100000000)
the space 21248K, 11% used [0x00000000fae00000, 0x00000000fb075440, 0x00000000fb075600, 0x00000000fc2c0000)
No shared spaces configured.

eden space 512K,from space 256K是 比例是2,SurvivorRatio=2 就是這個含義設置的意思 xmn表示新生代的值設置成1M,from區域就是s0區域,to區域就是s1區域,二者的大小是一樣的

eden space 512K, 33% used [0x00000000f9a00000, 0x00000000f9a2b300, 0x00000000f9a80000)
from space 256K, 99% used [0x00000000f9ac0000, 0x00000000f9affff8, 0x00000000f9b00000)
to space 256K, 0% used [0x00000000f9a80000, 0x00000000f9a80000, 0x00000000f9ac0000)

上面三者之和就是1M

真正在應用的場景中,已經盡量減少GC,將初始化的內存大小和最大內存大小配置成一樣,這樣可以減少GC

技術分享

package com.bjsxt.base001;

import java.util.Vector;

public class Test03 {

    public static void main(String[] args) {
        
        //-Xms1m -Xmx1m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=d:/Test03.dump
        //堆內存溢出
        Vector v = new Vector();
        for(int i=0; i < 5; i ++){
            v.add(new Byte[1*1024*1024]);
        }
        
    }
}

技術分享

上面這個代碼我申請5M的內存,但是在設置的時候卻是

/-Xms1m -Xmx1m 設置成1M,就會出現堆內存異常,使用-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath就會將信息導出來查看

技術分享

package com.bjsxt.base001;

public class Test04 {

    //-Xss1m  
    //-Xss5m
    
    //棧調用深度
    private static int count;
    
    public static void recursion(){
        count++;
        recursion();
    }
    public static void main(String[] args){
        try {
            recursion();
        } catch (Throwable t) {
            System.out.println("調用最大深入:" + count);
            t.printStackTrace();
        }
    }
}

技術分享

運行結果:

調用最大深入:12560
java.lang.StackOverflowError

jvm基礎知識1