JVM运行时数据区

目录

程序计数器(寄存器)(线程私有)

虚拟机栈(线程私有)

栈内存越大越好吗

方法内的局部变量线程安全吗

栈内存溢出

本地方法栈(线程私有)

堆(线程共享)

堆内存溢出

堆内存诊断

1.jps工具

2.jmap工具

3.jconsole工具

4.jvisualvm工具

方法区(线程共享)

内存溢出

运行时常量池

字符串常量池

变量拼接

编译期优化(常量拼接)

字符串延迟加载

串池特性

intern()

串池的位置

串池垃圾回收

StringTable性能调优

直接内存

内存溢出

释放原理


 

程序计数器(寄存器)(线程私有)

作用:是记住下一条jvm指令的地址

特点:是线程私有的

不会存在内存溢出

虚拟机栈(线程私有)

虚拟机栈-每个线程线程运行需要的内存空间

栈帧:每个方法运行时需要的内存

每个线程只能有一个活动栈帧(栈顶部的栈帧)

栈(windows除外根据虚拟内存大小划分)默认大小1024k

栈内存越大越好吗

固定500mb 分配1mb栈 可运行500个线程

分配100mb栈 可运行5个线程

栈内存越大方法递归调用次数越多(并不是越大越好)

一般采用系统默认大小

方法内的局部变量线程安全吗

线程安全 栈帧里面存的局部变量 每个线程都有一份

static的时候针对多个线程是共享的 (会有线程安全问题)

线程共享,会有安全问题

线程私有,不会有安全问题

如果作为方法返回值逃离方法作用范围被别的线程访问到就不安全

栈内存溢出

栈帧过多会导致栈内存溢出(方法递归调用)

栈帧过大(大小直接超过栈内存)

本地方法栈(线程私有)

native方法在本地方法栈,为本地方法提供运行空间

堆(线程共享)

通过new创建对象会使用堆内存

特点:是线程共享的,堆中对象度需要考虑线程安全问题,有垃圾回收机制

堆内存溢出

list集合不回收一直往进里面添加则堆溢出

(outofmemoryerror:内存不足)(javaheapspace)

-Xmx8m:设置堆空间8m

堆内存诊断

1.jps工具

查看当前系统中有哪些进程

2.jmap工具

查看堆内存占用情况(只能查询某一个时刻)

3.jconsole工具

图形界面的,多功能的检测工具,可以连续监测(线程 堆 cpu都可以检测 连续监测)

4.jvisualvm工具

可视化虚拟机内容 堆转储dump功能抓取快照 看前多少个大对象

可以排查内存占用过高

方法区(线程共享)

存储了类的结构相关信息 成员方法成员变量构造器

方法区是规范

hotspot在jdk1.8之前永久代(存在于堆中)

hotspot在jdk1.8之后元空间(用的本地内存,操作系统内存)

已经不由jvm管理内存结构

 

内存溢出

jdk1.8:默认使用内存16G,设置元空间大小可用来检测溢出

设置元空间大小8m

-XX:MaxMetaspaceSize-8m

异常出现OutOfMemoryError:Metaspace

jdk1.6:

设置永久代大小为8m

-XX:MaxPermSize-8m

异常出现OutOfMemoryError:PermGen space

运行时常量池

常量池:就是一张表,虚拟机根据这张常量表找到要执行的类名,方法名,参数类型,字面量等信息

运行时常量池:常理池是.class文件中的,当该类被加载,他的常量池信息就会放入运行时常量池,并把里面的符号地址变为真实地址

字符串常量池

变量拼接

执行到String s1="a"会将a对象放入串池中

String s2="b"

String s3="ab"(串池中)

String s4=s1+s2 (在堆中)先创建Stringbuilder对象

new StringBuilder().append("a").append("b").toString()

s3==s4//false

编译期优化(常量拼接)

String s5="a"+"b";直接在串池中找ab(已有)

s3==s5//true

java在编译器的优化 拼接结果ab确定

字符串延迟加载

执行一行代码再放入串池

串池特性

常量池中的字符串仅是符号,第一次用到时才变为对象

利用串池的机制,来避免重复创建字符串对象

字符串变量拼接的原理是StringBuilder(1.8)

字符串常量拼接的原理是编译器优化

可以使用intern方法,主动将串池中还没有的字符串对象放入串池

intern()

将字符串对象尝试放入串池,如果有则不会放入

如果没有则放入串池,会把串池中的对象返回

String s=new String("a")+new String("b");

这时串池中有"a","b",最后返回一个new String("ab")存在于堆中

string s2=s.intern();

s2=="ab"//true

这时的ab常量直接取存在于串池中的ab

串池的位置

1.6在是常量池的一部分 存在永久代中

内存不足触发永久代内存不足(PermGen space)

1.8从永久代放入堆中(不存在于常量池中) 优化了回收效率

内存不足触发堆内存不足(GC overhead limit exceeded)(heap space)

串池垃圾回收

无引用的minerGC

StringTable性能调优

存取大量字符串

调整-XX-StringTableSize=桶个数

考虑将字符串是否入池

直接内存

常见于nio操作,用于数据缓冲区

分配回收成本较高,但读写性能高

不收jvm内存回收管理

 

加入直接内存

少了一次缓冲区复制操作

 

内存溢出

(out of memery error)direct buffer memory

释放原理

通过Unsafe类(不属于java内存)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

outlier--

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

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

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

打赏作者

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

抵扣说明:

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

余额充值