系统相关
首页 > 系统相关> > jvm1--内存结构

jvm1--内存结构

作者:互联网

一、jvm内存结构

在这里插入图片描述

1、程序计数器(寄存器)

作用:是记住下一条 jvm指令的执行地址
特点:是线程私有的,不会存在内存溢出

2、栈

2.1 方法内的局部变量是否线程安全?
如果方法内局部变量没有逃离方法的作用访问,它是线程安全的
如果是局部变量引用了对象,并逃离方法的作用范围,需要考虑线程安全
2.2 栈内存溢出 StackOverflowError
栈帧过多导致栈内存溢出
栈帧过大导致栈内存溢出

3、本地方法栈

调用本地系统提供native的栈

4、堆

通过 new 关键字,创建对象都会使用堆内存

4.1、特点

它是线程共享的,堆中对象都需要考虑线程安全的问题。有垃圾回收机制

5、方法区(永久代-元空间)

5.1定义

逻辑上是堆的一部分,但是jvm厂商实现不一定遵从

5.2结构

idk1.6
在这里插入图片描述
因为串池用的很频繁,但是只有老年代不足时才会触发FULLGC,这样的频率不高,容易造成溢出,所以将它转移到了堆内存中
在这里插入图片描述

5.3运行时常量池

1)常量池,就是一张表,虚拟机指令根据这张常量表找到要执行的类名、方法名、参数类型、字面量等信息
在这里插入图片描述
2)运行时常量池,常量池是 *.class 文件中的,当该类被加载,它的常量池信息就会放入运行时常量池,并把里面的符号地址变为真实地址
上图中的#1、2等会变成运行时的真实地址

5.4 StringTable 特性(串池)

1)常量池中的字符串仅是符号,第一次用到时才变为对象
2)利用串池的机制,来避免重复创建字符串对象
3)字符串变量拼接的原理是 StringBuilder (1.8 new对象在堆里)
4)字符串常量拼接的原理是编译期优化
5)可以使用 intern 方法,主动将串池中还没有的字符串对象放入串池
6)1.8 将这个字符串对象尝试放入串池,如果有则并不会放入,如果没有则放入串池, 会把串池中的对象返回
1.6 将这个字符串对象尝试放入串池,如果有则并不会放入,如果没有会把此对象复制一份,放入串池, 会把串池中的对象返回
在这里插入图片描述s3==s5!=s4

5.5 StringTable优化

因为StringTabl底层是hashtable,调整桶个数会影响入池的效率。桶太少,链表长发生hash碰撞概率大。效率慢。
调整 -XX:StringTableSize=桶个数(默认60000)

6、直接内存

6.1、定义

常见于 NIO 操作时,用于数据缓冲区
分配回收成本较高,但读写性能高
不受 JVM 内存回收管理
在这里插入图片描述

在这里插入图片描述
普通io和nio
nio在系统内存中开辟出直接内存,java可以直接访问,更快

6.2 分配和回收原理

使用了 Unsafe 对象完成直接内存的分配回收,并且回收需要主动调用 freeMemory 方法
ByteBuffer 的实现类内部,使用了 Cleaner (虚引用)来监测 ByteBuffer 对象,一旦
ByteBuffer 对象被垃圾回收,那么就会由 ReferenceHandler 线程通过 Cleaner 的 clean 方法调
用 freeMemory 来释放直接内存

标签:常量,--,jvm1,对象,线程,内存,串池,放入
来源: https://blog.csdn.net/qq_35841637/article/details/109962612