jvm区域

内存分布

方法区

1
2
线程共享
已被虚拟机加载的类型信息,常量,静态变量,即时编译器编译后的代码缓存等数据.

运行时常量池

1
2
3
4
5
方法区的一部分,class文件中除了有类的版本,字段,方法,接口等描述信息外,
还有一项是常量池表(constant pool table),
用于存放编译期生成的各种字面量和符合引用这部分内容在类加载后存放到方法区的运行时常量池中.
常量池具有动态性:比如string的intern()方法
抛错: outofmemoryerror

虚拟机栈

1
2
3
4
5
6
7
8
9
10
线程私有
虚拟机会创建一个栈帧,用来存储局部变量表,操作数栈,动态链接库,方法出口等信息

局部变量表:编译期可知的各种基本数据类型(boolean,byte,char,short,int,float,long,double)
对象引用(reference类型,不一定是对象本身,可能是一个执行对象起始地质队引用指针,也可能是一个代表对象的句柄或其他与对象相关的位置)
和returnAddress类型(执行一条字节码指令单地址)
存储空间使用变量槽(slot)来表示,64位的long和double占用2个slot,其他使用一个
局部变量表的内存空间在编译期间完成分配,后边就不会改变
抛错:请求栈深度大于虚拟机允许的深度->stackoverflowerror
jvm容量可扩展,当扩展无法申请到足够内存时>outofmemorterror

本地方法栈

1
2
3
4
5
6
7
-Xms   -Xmx
几乎所有的对象都存放在堆中,但是随着逃逸分析技术的强大,栈上分配,标量替换优化手段已经到知一些微妙的变化悄然发生,所以说都分配在堆上不是绝对的.
分配:
物理上不连续但是要求逻辑上是连续的
1 tlab 按照线程分配缓存

抛错: outofmemoryerror

程序计数器

1
2
3
4
5
线程私有
改变计数器的值,选取下一条需要执行的字节码执行
程序控制流的指示器,分支/循环/跳转/异常处理/线程恢复等功能都需要依赖这个
多线程通过线程轮流切换,分配处理器执行时间来实现,在任何时刻一个处理器只能处理一个执行,
程序计数器来记录这个位置

直接内存

1
2
3
jdk1.4加入
虽然不会受java堆大小限制,但是会受到本机总内存的限制
抛错: outofmemoryerror

对象创建

1
2
3
1,连续空间-->使用指针碰撞(谁先申请算谁的)[serial,parnew带压缩整理,简单高效]
2,不连续-->维护一个列表,那个是空闲的列表,分配后更新列表,分配方式叫(空闲列表(fee list))[cms基于清除算法的收集器,理论上就只能才用较为复杂的空闲列表来分配内存]
3,按照线程分配缓存-->成为本地线程分配(thread local allocation buffer,tlab)

对象的内存布局

1
2
3
4
5
6
7
8
9
10
11
12
对象在堆内存的储存布局分为3部分:对象头(header),实例数据(instance data),对齐填充(padding)
对象头包括2类信息
1,存储对象自身的运行时数据,比如 哈希码,gc分代年龄,锁撞他标识,线程持有的锁,偏向线程id,偏向时间戳等,在32和64位分别是32何64bit,官方称为mark word.

哈希码,分代年龄 01 未锁定
指向锁记录的指针 00 轻量级锁定
指向重量级锁的指针 10 膨胀(重量级锁定)
空,不需要记录信息 11 gc标记
偏向线程id,偏向时间戳,对象分带年龄 01 可偏向


2,类型指针,对象指向它的类型元数据的指针,jvm通过这个嘞确定对象是哪个类的实例

对象的访问定位

1
2
3
4
5
6
7
8
9
10
11
12
13
14
方式
1,句柄
本地变量表->reference->堆(句柄池)->对象实例数据
->方法区(对象类型数据)
reference中存储的是稳定的句柄,在对象被移动(垃圾收集)时只会改变句柄中的实例数据指针,而reference本身不需要被修改

2,指针
北地变量表->reference->堆(到对象类型数据的指针)->方法区(对象类型数据)
->对象实例数据
速度快,节省一次指针定位到时间开销,由于对象访问在java中非常频繁,因此这类开销积少成多也是一项极为可观的执行成本



hotspot使用指针进行对象访问,例外使用shenandoah收集器也会有一次额外的转发

实战内存异常

1
2
3
-Xms -Xmx
list.add(new object())
outofmemoryerror

1
2
3
-Xss
方法递归
stackoverflowerror

方法区和运行时常量池溢出

1
2
3
4
5
-XX:PermSize  -XX:MaxPerSize  
string.intern
outofmemoryerror

-XX:MAxMetaspaceSize

直接内存

1
2
3
-XX:MaxDirectMemorySize
默认和-Xmx一致
unsafe.allcatememory分配内存