JVM性能调优-理解JVM内存区域+常量池问题

概述

  1. 线程私有(运行指令):程序计数器、虚拟机栈、本地方法栈
  2. 线程共享(存储数据):堆、方法区(Java8去掉了)
    在这里插入图片描述

程序计数器

唯一不会OOM
指向当前线程正在执行的字节码指令的地址(行号)

存储当前线程方法所需的数据、指令、返回地址
-Xss 1M
每个方法在执行的时候都会创建一个栈帧

  1. 局部变量表
  2. 操作数帧
  3. 动态连接
  4. 返回地址

本地方法栈

保存native方法的信息,调用native方法时,不在虚拟机栈中创建栈帧,JVM只是简单动态链接并直接调用native方法

HotSpot直接把本地方法栈和虚拟机栈合二为一了

方法区

JDK1.7及之前称为永久代
JDK1.8及之后称为元空间

  1. 类信息
  2. 常量 final
  3. 静态变量
  4. 即时编译期编译后的代码

-Xms、-Xmx、-Xmn
几乎所有对象都是在堆上分配的。

JVM各版本内存区域变化

  1. 运行时常量池:
    Class文件中的常量池(编译期生成的各种字面量和符号引用)会在类加载后放入这个区域
    1.1 符号引用:在编译时,引用的对象并不知道实际的内存地址,因此只能用一个符号引用来代替,而在类装载之后是知道内存地址的,此时会将符号引用替换成实际地址。
    1.2 文本字符String a = “abc”,这个abc 就是字面量;八种基本类型int a = 1; 这个1 就是字面量;声明为final 的常量

  2. JDK1.6 :
    常量池在方法区

  3. JDK1.7及之后
    常量池在堆

  4. JDK1.8
    去方法区,使用元空间来代替(元空间大小只受机器内存限制)
    永久代存储类信息、常量等数据可能会内存溢出
    对永久代调优很困难

直接内存

JVM直接管理不了的,不是JVM规范中定义的内存区域

  1. 如果使用NIO,直接内存会经常使用,在java中可以使用directByteBuffer对象直接引用并操作
  2. 这块内存不受堆大小限制,可以通过MaxDirectMemorySize来设置,默认与最大堆大小一致,所以也会OOM
  3. 避免在堆和本地内存中来回复制数据

问题

  1. 为什么需要程序计数器
    Java是多线程的,意味着线程是要切换的,同时确保多线程情况下程序能够正常运行。

  2. 字符串创建与比较

    public static void main(String[] args) {
        String s1 = "Hello";
        String s2 = "Hello";
        String s3 = "Hel" + "lo";
        String s4 = "Hel" + new String("lo");
        String s5 = new String("Hello");
        String s6 = s5.intern();
        String s7 = "H";
        String s8 = "ello";
        String s9 = s7 + s8;
        System.out.println(s1 == s2);  // true
        System.out.println(s1 == s3);  // true
        System.out.println(s1 == s4);  // false
        System.out.println(s1 == s9);  // false
        System.out.println(s4 == s5);  // false
        System.out.println(s1 == s6);  // true
    }

2.1 s1在常量池创建了常量
2.2 s2由于常量池已有了Hello常量,与s1的指向常量的地址是一样的
2.3 s3 Hel和lo是字面量,编译期会进行优化,编译时就替换成Hello了,与s2一样
2.4 lo是通过new对象创建出来的,需要在运行期才能确定具体的地址,因此和s1的地址不同
2.5 new出来的对象,虽然Hello在常量池是和s1一样,但是当前对象返回给s5的地址是堆中的对象地址
2.6 返回的是常量池中的Hello的地址,与s1一样
2.7 s9 是由两个变量拼接的,编译期无法优化,只能在运行期才知道具体的地址

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值