Jvm-4—方法区

        Person p = new Person();

        方法区可以看作是一个独立于堆的内存空间,非堆。方法区和堆一样,是线程共享的,方法区的大小决定了可以存放多少类。如果类加载过多,同样会内存溢出。

jdk1.7以前 成为永久代;1.8后,成为元空间。有本质上的区别,永久代使用的虚拟机内存,而元空间(即方法区)使用的是本地内存。

        4.1 方法区大小设置

-XX:MetaspaceSize=100m  -XX:MaxMetaspaceSize=100m

默认情况下  最小为21m  最大为-1 表示没有限制

建议将MetaspaceSize设置为一个较高的值,如果初始值较低,实际内存大小一旦超过就会引发Full GC,影响性能。

内存泄漏:对象已经失效,但是和引用之间的关联没有断开,导致GC时无法回收空间。

内存溢出:生成对象所用的实际大小超过了可用内存大小。

        4.2 方法区的内部结构

        1.类型信息:类、接口、枚举、方法的信息

        2. 常量信息 加载时即被确认,存放于运行时常量池。

        

/**
 * Project:TODO ADD PROJECT NAME
 * Modify Information:
 */
package main.FirstDemo.jvm;

import java.io.Serializable;

/**

 */
public class MetaSpace2 extends Object implements Comparable<String>, Serializable {

    public int num = 10;
    private static String str = "测试字符串";
    //空构造器

    public void test1(){
        int count = 20;
        System.out.println("count="+count);
    }

    public static int test2(int cal){
        int result = 0;

        try{
            int value = 30;
            result = value/cal;
        }catch (Exception w){

        }
        return result;
    }
    @Override
    public int compareTo(String o) {
        return 0;
    }
}

//字节码文件

Classfile /D:/IdeaProjects/java-web/out/production/java-web/main/FirstDemo/jvm/Metaspace2.class
  Last modified 2021-6-27; size 1512 bytes
  MD5 checksum d8a1138b3900f740e6878fcc45f4c69b
  Compiled from "MetaSpace2.java"

//类型信息
public class main.FirstDemo.jvm.MetaSpace2 extends java.lang.Object implements java.lang.Comparable, java.io.Serializable
  minor version: 0
  major version: 52
  flags: ACC_PUBLIC, ACC_SUPER

//常量池
Constant pool:
   #1 = Methodref          #17.#49        // java/lang/Object."":()V
   #2 = Fieldref           #16.#50        // main/FirstDemo/jvm/MetaSpace2.num:I
   #3 = Fieldref           #51.#52        // java/lang/System.out:Ljava/io/PrintStream;
   #4 = Class              #53            // java/lang/StringBuilder
   #5 = Methodref          #4.#49         // java/lang/StringBuilder."":()V
   #6 = String             #54            // count=
   #7 = Methodref          #4.#55         // java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   #8 = Methodref          #4.#56         // java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
   #9 = Methodref          #4.#57         // java/lang/StringBuilder.toString:()Ljava/lang/String;
  #10 = Methodref          #58.#59        // java/io/PrintStream.println:(Ljava/lang/String;)V
  #11 = Class              #60            // java/lang/Exception
  #12 = Class              #61            // java/lang/String
  #13 = Methodref          #16.#62        // main/FirstDemo/jvm/MetaSpace2.compareTo:(Ljava/lang/String;)I
  #14 = String             #63            // 测试字符串
  #15 = Fieldref           #16.#64        // main/FirstDemo/jvm/MetaSpace2.str:Ljava/lang/String;
  #16 = Class              #65            // main/FirstDemo/jvm/MetaSpace2
  #17 = Class              #66            // java/lang/Object
  #18 = Class              #67            // java/lang/Comparable
  #19 = Class              #68            // java/io/Serializable
  #20 = Utf8               num
  #21 = Utf8               I
  #22 = Utf8               str
  #23 = Utf8               Ljava/lang/String;
  #24 = Utf8              
  #25 = Utf8               ()V
  #26 = Utf8               Code
  #27 = Utf8               LineNumberTable
  #28 = Utf8               LocalVariableTable
  #29 = Utf8               this
  #30 = Utf8               Lmain/FirstDemo/jvm/MetaSpace2;
  #31 = Utf8               test1
  #32 = Utf8               count
  #33 = Utf8               test2
  #34 = Utf8               (I)I
  #35 = Utf8               value
  #36 = Utf8               cal
  #37 = Utf8               result
  #38 = Utf8               StackMapTable
  #39 = Class              #60            // java/lang/Exception
  #40 = Utf8               compareTo
  #41 = Utf8               (Ljava/lang/String;)I
  #42 = Utf8               o
  #43 = Utf8               (Ljava/lang/Object;)I
  #44 = Utf8              
  #45 = Utf8               Signature
  #46 = Utf8               Ljava/lang/Object;Ljava/lang/Comparable;Ljava/io/Serializable;
  #47 = Utf8               SourceFile
  #48 = Utf8               MetaSpace2.java
  #49 = NameAndType        #24:#25        // "":()V
  #50 = NameAndType        #20:#21        // num:I
  #51 = Class              #69            // java/lang/System
  #52 = NameAndType        #70:#71        // out:Ljava/io/PrintStream;
  #53 = Utf8               java/lang/StringBuilder
  #54 = Utf8               count=
  #55 = NameAndType        #72:#73        // append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
  #56 = NameAndType        #72:#74        // append:(I)Ljava/lang/StringBuilder;
  #57 = NameAndType        #75:#76        // toString:()Ljava/lang/String;
  #58 = Class              #77            // java/io/PrintStream
  #59 = NameAndType        #78:#79        // println:(Ljava/lang/String;)V
  #60 = Utf8               java/lang/Exception
  #61 = Utf8               java/lang/String
  #62 = NameAndType        #40:#41        // compareTo:(Ljava/lang/String;)I
  #63 = Utf8               测试字符串
  #64 = NameAndType        #22:#23        // str:Ljava/lang/String;
  #65 = Utf8               main/FirstDemo/jvm/MetaSpace2
  #66 = Utf8               java/lang/Object
  #67 = Utf8               java/lang/Comparable
  #68 = Utf8               java/io/Serializable
  #69 = Utf8               java/lang/System
  #70 = Utf8               out
  #71 = Utf8               Ljava/io/PrintStream;
  #72 = Utf8               append
  #73 = Utf8               (Ljava/lang/String;)Ljava/lang/StringBuilder;
  #74 = Utf8               (I)Ljava/lang/StringBuilder;
  #75 = Utf8               toString
  #76 = Utf8               ()Ljava/lang/String;
  #77 = Utf8               java/io/PrintStream
  #78 = Utf8               println
  #79 = Utf8               (Ljava/lang/String;)V
{

    //域信息
  public int num;
    descriptor: I
    flags: ACC_PUBLIC

  private static java.lang.String str;
    descriptor: Ljava/lang/String;
    flags: ACC_PRIVATE, ACC_STATIC

  public main.FirstDemo.jvm.MetaSpace2();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=2, locals=1, args_size=1
         0: aload_0
         1: invokespecial #1                  // Method java/lang/Object."":()V
         4: aload_0
         5: bipush        10
         7: putfield      #2                  // Field num:I
        10: return
      LineNumberTable:
        line 33: 0
        line 35: 4
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0      11     0  this   Lmain/FirstDemo/jvm/MetaSpace2;

//方法信息  

public void test1();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=3, locals=2, args_size=1
         0: bipush        20
         2: istore_1
         3: getstatic     #3                  // Field java/lang/System.out:Ljava/io/PrintStream;
         6: new           #4                  // class java/lang/StringBuilder
         9: dup
        10: invokespecial #5                  // Method java/lang/StringBuilder."":()V
        13: ldc           #6                  // String count=
        15: invokevirtual #7                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
        18: iload_1
        19: invokevirtual #8                  // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
        22: invokevirtual #9                  // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
        25: invokevirtual #10                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
        28: return
      LineNumberTable:
        line 40: 0
        line 41: 3
        line 42: 28
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0      29     0  this   Lmain/FirstDemo/jvm/MetaSpace2;
            3      26     1 count   I

  public static int test2(int);
    descriptor: (I)I
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=3, args_size=1
         0: iconst_0
         1: istore_1
         2: bipush        30
         4: istore_2
         5: iload_2
         6: iload_0
         7: idiv
         8: istore_1
         9: goto          13
        12: astore_2
        13: iload_1
        14: ireturn

//异常信息表  从2-9(字节码指令地址)能包裹住的代码
      Exception table:
         from    to  target type
             2     9    12   Class java/lang/Exception
      LineNumberTable:
        line 45: 0
        line 48: 2
        line 49: 5
        line 52: 9
        line 50: 12
        line 53: 13
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            5       4     2 value   I
            0      15     0   cal   I
            2      13     1 result   I
      StackMapTable: number_of_entries = 2
        frame_type = 255 /* full_frame */
          offset_delta = 12
          locals = [ int, int ]
          stack = [ class java/lang/Exception ]
        frame_type = 0 /* same */

  public int compareTo(java.lang.String);
    descriptor: (Ljava/lang/String;)I
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=2, args_size=2
         0: iconst_0
         1: ireturn
      LineNumberTable:
        line 57: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       2     0  this   Lmain/FirstDemo/jvm/MetaSpace2;
            0       2     1     o   Ljava/lang/String;

  public int compareTo(java.lang.Object);
    descriptor: (Ljava/lang/Object;)I
    flags: ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC
    Code:
      stack=2, locals=2, args_size=2
         0: aload_0
         1: aload_1
         2: checkcast     #12                 // class java/lang/String
         5: invokevirtual #13                 // Method compareTo:(Ljava/lang/String;)I
         8: ireturn
      LineNumberTable:
        line 33: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       9     0  this   Lmain/FirstDemo/jvm/MetaSpace2;

//方法  

static {};
    descriptor: ()V
    flags: ACC_STATIC
    Code:
      stack=1, locals=0, args_size=0
         0: ldc           #14                 // String 测试字符串
         2: putstatic     #15                 // Field str:Ljava/lang/String;
         5: return
      LineNumberTable:
        line 36: 0
}
Signature: #46                          // Ljava/lang/Object;Ljava/lang/Comparable;Ljava/io/Serializable;
SourceFile: "MetaSpace2.java"

========================================================

        public static int count = 1; //准备阶段赋零值  初始化阶段赋真实值

        public static final int number = 2;  //编译的时候就赋真实值

Jvm-4—方法区

        4.3 运行时常量池

        常量池

        类和接口编译后会产生一个字节码文件,而字节码需要数据支持,通常这种数据会很大以至于不能支持存到字节码里。因此将这些数据存到常量池,字节码中包含了指向常量池的引用。

        运行时常量池

        运行时常量池是方法区的一部分,Jvm为每一个已加载的类和接口都会维护一个常量池。运行时常量池包含多种不同的常量,包括编译期已经确认的数值字面量,也包括到运行期解释后才能获得的方法或字段引用。注意此时不是常量池中的符号引用了,而是真实的引用地址。在Java语言中,并不要求常量只能在编译期间产生,运行期间一样也可以让新常量入池,像String类的intern()方法就能做到新常量入池的操作,这就是运行时常量池的动态性表现了。

        4.4 方法区的演进

Jvm-4—方法区

        1.StringTable为什么会移到堆区?

        因为jdk1.6中当字符串存储在永久代时,只有永久代空间满了 才会触发Full GC,导致字符串回收效率很低,放到堆里能及时回收内存。

        2.静态变量

        private static byte[] arr = new byte[1024*1024*100]

        注意:byte数组具体的值一直是存放于堆中  arr的引用位置是随着jdk发生了变化。

上一篇:javap反编译


下一篇:基于ssm框架开发的图书馆管理系统