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