JAVA内存模型

https://pic1.zhimg.com/80/v2-d2ee81a2f5d3be14f4766c9d030d1c40_hd.jpg

内存模型

1、程序计数器:

当前线程正在执行的字节码行号指示器,唯一没有规定OOM的区域;

2、JAVA虚拟机栈:

由一个一个的栈帧组成,每一个方法的执行,对应着一个栈帧在虚拟机栈中入栈、出栈,可以抛出StackOverflowError(栈深度超过虚拟机栈最大深度)、OutOfMemoryError(虚拟机在扩展时无法申请到内存)异常。栈帧的结构包括:

3、局部变量表:

连续的内存空间,存放方法参数和局部变量,还有八大基本类型、对象引用reference)、returnAddress类型;

        3.1 操作数栈:

虚拟机栈用于计算临时数据的存储区;

        3.2 动态链接:

将方法区中的符号引用转化为直接引用的过程;

        3.3 方法出口:

下一个方法指令的地址;

4、本地方法栈:

和JAVA虚拟机栈几乎一样,区别在于它执行的native方法;

5、堆:

堆是JAVA内存管理中最大的一块,也是内存回收主要发生区域;

堆被所有线程共享,但是线程的工作内存上的内容是线程独享的;

对象数组都是在堆上分配的,但是不是所有的对象都是在堆上分配的,因为有JIT编译器的优化

JAVA通过逃逸分析来判断对象是否只在栈上使用,如果是的话,就通过标量替换来实现栈上分配

6、方法区:

加载的类定义数据常量区静态变量JIT编译后的代码

HotSpot中的永久代

存储变量的元数据信息;

线程安全、大小不固定、可以被垃圾回收;

常量池包括:

        6.1 Class常量池:

每一个class文件都有一个Class常量池

Class文件中包含了类的版本字段方法接口等;

常量池里包含了字面量符号引用

                6.1.1 字面量:

文本字符串、八大基本类型、声明为Final的常量等;

                6.1.2 符号引用:

类和方法的全限定名、字段的名称和描述、方法的名称和描述;

        6.2 运行时常量池:

运行时常量池就是Class常量池加载到内存后的版本;

不同之处在于,它的字面量可以动态的添加、符号引用会被解析为直接引用

        6.3 字符串常量池:

存储一个StringTable,是一个HashSet表,这个StringTable的实例只有一个,被所有线程共享

从1.7开始,被移到堆里了,因为方法区的空间太小了;

正常新建字符串,是在先去常量池中找有没有这个字符串,有的话就直接返回,没有的话,再在常量池中新建一个返回;

使用new的方式一定会在堆里新建字符串,Java1.7之后,使用intern函数,会先去常量池中找有没有,有的话直接返回,如果是在堆中,则将堆中的地址返回给常量池,再返回常量池中的引用;

String str = “JA” + “VA”;

String str = “JAVA”;

编译器会将第一句优化成第二句;

String str2 = str1 + “test”;

编译器会将上面这句优化为使用;


对象访问定位:

1、句柄访问:

Reference中存的是稳定的句柄,在垃圾回收时比较稳定;

https://pic3.zhimg.com/80/v2-657acbff3abc53c74efad9ed0688415e_hd.jpg

2、直接指针访问:

访问速度快,节省了一次指针定位开销;

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值