JVM:方法区


栈、堆、方法区的交互关系

从线程共享与否的角度来看

在这里插入图片描述

在这里插入图片描述

方法区的理解

方法区在哪里?

在这里插入图片描述

方法区的基本理解

在这里插入图片描述

HotSpot中方法区的演进

在这里插入图片描述

在这里插入图片描述

方法区概述

在这里插入图片描述

设置方法区大小与OOM

  • 方法区的大小不必是固定的,JVM可以根据应用的需要动态调整

  • JDK7及以前

在这里插入图片描述

  • JDK8及以后

在这里插入图片描述

如何解决这些OOM?

在这里插入图片描述

方法区的内部结构

示意图

在这里插入图片描述

方法区(Method Area)存储什么?

在这里插入图片描述

类型信息

在这里插入图片描述

域(Field)信息

在这里插入图片描述

方法(Method)信息

在这里插入图片描述

non-final的类变量

  • 静态变量和类关联在一起,随着类的加载而加载,他们成为类数据在逻辑上的一部分

  • 类变量被类的所有实例共享,即使没有类实例时也可以访问它

    /**
     * non-final的类变量
     */
    public class MethodAreaTest {
        public static void main(String[] args) {
            Order order = null;
            order.hello();
            System.out.println(order.count);
        }
    }
    
    class Order {
        public static int count = 1;
        public static final int number = 2;
    
        public static void hello() {
            System.out.println("hello!");
        }
    }
    

全局常量:static final

被声明为final的类型变量的处理方法则不同,每个全局常量在编译的时候就会被分配

运行时常量池VS常量池

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

为什么需要常量池?

在这里插入图片描述

常量池中有什么?

在这里插入图片描述

小结

常量池,可以看做是一张表,虚拟机指令根据这张常量表找到要执行的类名、方法名、参数类型、字面量等类型

运行时常量池

在这里插入图片描述

方法区使用举例

public class MethodAreaDemo {
    public static void main(String[] args) {
        int x = 500;
        int y = 100;
        int a = x / y;
        int b = 50;
        System.out.println(a + b);
    }
}
Code:
      stack=3, locals=5, args_size=1
         0: sipush        500
         3: istore_1
         4: bipush        100
         6: istore_2
         7: iload_1
         8: iload_2
         9: idiv
        10: istore_3
        11: bipush        50
        13: istore        4
        15: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
        18: iload_3
        19: iload         4
        21: iadd
        22: invokevirtual #3                  // Method java/io/PrintStream.println:(I)V
        25: return

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

方法区的演进细节

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

永久代为什么要被元空间替换?

在这里插入图片描述

StringTable为什么要调整?

在这里插入图片描述

静态变量放在哪里

/**
 * 结论:
 * 静态引用对应的对象实体始终都存在堆空间
 *
 * jdk7:
 * -Xms200m -Xmx200m -XX:PermSize=300m -XX:MaxPermSize=300m -XX:+PrintGCDetails
 * jdk 8:
 * -Xms200m -Xmx200m -XX:MetaspaceSize=300m -XX:MaxMetaspaceSize=300m -XX:+PrintGCDetails
 */
public class StaticFieldTest {
    private static byte[] arr = new byte[1024 * 1024 * 100];//100MB

    public static void main(String[] args) {
        System.out.println(StaticFieldTest.arr);

        try {
            Thread.sleep(1000000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
/**
 * 《深入理解Java虚拟机》中的案例:
 * staticObj、instanceObj、localObj存放在哪里?
 */
public class StaticObjTest {
    static class Test {
        static ObjectHolder staticObj = new ObjectHolder();
        ObjectHolder instanceObj = new ObjectHolder();

        void foo() {
            ObjectHolder localObj = new ObjectHolder();
            System.out.println("done");
        }
    }

    private static class ObjectHolder {
    }

    public static void main(String[] args) {
        Test test = new StaticObjTest.Test();
        test.foo();
    }
}

方法区的垃圾回收

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

总结

在这里插入图片描述

常见面试题

在这里插入图片描述

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值