5.运行时数据区-字符串常量池、程序计数器、直接内存

概述

相关文章在此总结如下:

文章地址
jvm基本知识地址
jvm类加载系统地址
双亲委派模型与打破双亲委派地址
运行时数据区地址

字符串常量池

字符串常量池存储数据的方式

字符串常量池使用的是StringTable的数据结构存储数据,类似于HashTable(哈希表)

注意: 双引号表示的字符串,默认都是存在字符串常量池的。堆内存中的字符串想进入字符串常量池,也不是不可的。

在这里插入图片描述

三种常量池

  • Class文件常量池
  • 运行时常量池
  • 字符串常量池

字面量与符号引用

字面量: int 、float、long、double、双引号字符串等
符号引用:Class、Method、Field等

哈希表

哈希表(也叫散列表),是根据关键码值(K-V)而直接进行访问的数据结构。本质上就是个数组+链表

在这里插入图片描述

  • key:散列函数,公式:hash(字符串) % 数组size
  • value:字符串的引用
  • size: -XX:StringTableSize=65536
    目标:加速查找速度

实战

测试案例如下:

package com.fun.classloader;

/**
 * 测试字符串常量池
 */
public class TestStringPool {
    public static void main(String[] args) {
        test();
    }

    public static void test() {
        String str1 = "abc";
        String str2 = new String("abc");
        // false  == 比较的是对象内存地址
        System.out.println(str1 == str2);

        String str3 = new String("abc");
        // false
        System.out.println(str2 == str3);

        // 编译期会计算出 "ab"
        String str4 = "a" + "b";
        // true
        System.out.println(str4 == "ab");

        String s1 = "a";
        String s2 = "b";
        String str6 = s1 + s2;
        // false 变量相加运行期计算
        System.out.println(str6 == "ab");

        // 带方法的运算也是运行期计算
        String str7 = "abc".substring(0, 2);
        // false
        System.out.println(str7 == "ab");

        String s5 = "a";
        String s6 = "abc";
        String s7 = s5 + "bc";

        // true
        System.out.println(s6 == s7.intern());
    }
}

在这里插入图片描述

总结如下:

  • 单独使用""引号创建的字符串都是常量,编译期就已经确定存储到字符串常量池中
  • 使用 new String(“”) 创建的对象会存储到 heap 中,是运行期新创建的
  • 使用只包含常量的字符串连接符,如:“a”+“b” 创建的也是常量,编译期就已经确定存储到字符串常量池中
  • 使用包含变量的字符串连接如 “a” + s 创建的对象是运行期才创建的,存储到 heap 中
  • 运行期调用 String 的 intern() 方法可以向字符串常量池中动态添加对象

程序计数器

程序计数器,也叫PC寄存器、当前线程所执行的字节码指令行号指示器

**注意:**线程切换(系统上下文切换) 后准确恢复执行位置,需要知道执行到的位置

存储数据

  • java 方法:记录虚拟机字节码指令地址
  • native方法:记录为空

异常:唯一没有OOM异常的区域

直接内存

直接内存不是虚拟机运行时数据区的一部分,也不是 java 虚拟机规范 中定义的内存区域

在 jdk1.4 中,新加了 NIO,引入了 Channel 和 Buffer 的 IO 方式,可以使用 native 方法直接分片对外内存,然后通过 DirectByteBuffer 对象可以操作直接内存。

直接内存与堆内存比较

内存区域分配空间读写操作
堆内存性能很好效率低
直接内存性能很差效率高

结束

至此,字符串常量池、程序计数器、直接内存,就结束了,如有疑问,欢迎评论区留言。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

流月up

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值