jvm内存结构
根据jvm规范,jvm内存分为虚拟机栈、堆、方法区、程序计数器、本地方法栈
java8和Java7的区别
方法区的实现,Java7方法区的实现是永久代,Java8方法区的实现是元空间。
方法区Java8之后的变化:
- 移除元空间,替换为永久代
- 永久代中的类元信息转移到本地内存
- 永久代中的字符串常量池和类静态变量转移到了堆
- 永久代参数变为元空间参数
将永久代替换为元空间原因:
- 字符串在永久代,容易出现性能问题和内存溢出
- 类及方法信息比较难确定大小,对于永久代的大小制定比较困难
- 永久代会提高gc复杂度,并且回收率偏低
程序计数器
虚拟机栈
线程私有
- 虚拟机栈
和线程同时创建,用于存储栈帧。
每个方法在执行时都会创建一个栈帧(Stack Frame),用于存储局部变量表、操作数栈、动态链接、方法出口等信息
- 栈帧(Stack Frame)
用于支持虚拟机进行方法调用和方法执行的数据结构。
存储了方法的局部变量表、操作数栈、动态连接和方法返回地址等信息。
大小设置:
-Xss1m
-Xss1024k
-Xss1048576
- 局部变量表
- 操作数栈
- 动态链接
- 方法返回地址
本地方法栈
类似于虚拟机栈,
区别:虚拟机栈为虚拟机执行Java方法服务,本地方法栈为虚拟机执行本地方法服务
堆
堆的概念
线程共享
几乎所有对象都在这里分配内存
例外:逃逸分析技术
- 设置堆空间的大小
-Xmx20m -Xms5m
- 堆的分类
年轻代和老年代
- JVM中存储java对象可以被分为两类:
- 年轻代:主要存放新创建的对象,内存相对较小,垃圾回收较频繁。年轻代分成1个Eden Space和2个Suvivor Space(from 和to)
- 年老代:主要存放JVM认为生命周期比较长的对象(经过几次的Young Gen的垃圾回收后仍然存在),内存大小相对会比较大,垃圾回收也相对没有那么频繁。
- 配置新生代和老年代堆结构占比
- 默认 -XX:NewRatio=2 , 标识新生代占1 , 老年代占2 ,新生代占整个堆的1/3
修改占比 -XX:NewPatio=4 , 标识新生代占1 , 老年代占4 , 新生代占整个堆的1/5
- Eden空间和另外两个Survivor空间占比分别为8:1:1
可以通过操作选项 -XX:SurvivorRatio 调整这个空间比例。 比如 -XX:SurvivorRatio=8
对象分配过程
分配过程
1.new的对象先放在伊甸园区。该区域有大小限制
2.当伊甸园区域填满时,程序又需要创建对象,JVM的垃圾回收器将对伊甸园预期进行垃圾回收(Minor GC),将伊甸园区域中不再被其他对象引用的额对象进行销毁,再加载新的对象放到伊甸园区
3.然后将伊甸园区中的剩余对象移动到幸存者0区
4.如果再次触发垃圾回收,此时上次幸存下来的放在幸存者0区的,如果没有回收,就会放到幸存者1区
5.如果再次经历垃圾回收,此时会重新返回幸存者0区,接着再去幸存者1区。
6.如果累计次数到达默认的15次,这会进入养老区。
可以通过设置参数,调整阈值 -XX:MaxTenuringThreshold=N
7.养老区内存不足是,会再次出发GC:Major GC 进行养老区的内存清理
8.如果养老区执行了Major GC后仍然没有办法进行对象的保存,就会报OOM异常.
堆GC
GC分两种:
- 部分收集器(partial GC)
- 新生代收集(minor GC/yong GC):只是新生代的垃圾收集
- 老年代收集(major GC/old GC):只是老年代的垃圾收集
- 混合收集(mixed GC):收集整个新生代及老年代的垃圾收集(G1 GC)
- 整堆收集器(Full GC):收集整个Java堆和方法区的垃圾收集器
触发条件:
- 年轻代GC:年轻代空间不足
- 老年代GC:老年代空间不足,速度比minor GC慢10倍以上
- fullGC:调用System.go(),系统会执行full GC,不是立即执行
方法区
线程共享
用于存储已被jvm加载的类型信息、常量、静态变量、即时编译器编译后的代码缓存等数据
元空间、永久代是方法区具体的落地实现。方法区看作是一块独立于Java堆的内存空间,它主要是用来存储所加载的类信息的
Java8以后,设置元空间大小:
元数据区大小可以使用参数 -XX:MetaspaceSize 和 -XX:MaxMetaspaceSize指定
默认值依赖于平台。windows下,-XX:MetaspaceSize是21M,-XX:MaxMetaspaceSize的值是-1,即没有限制。
运行时常量池
常量池vs运行时常量池
字节码文件中,内部包含了常量池
方法区中,内部包含了运行时常量池
常量池:存放编译期间生成的各种字面量与符号引用
运行时常量池:常量池表在运行时的表现形式