jvm的位置:
jvm体系结构
jvm调优调的是方法区和栈
类加载器
作用:加载Class文件~
1、虚拟机自带的加载器
2、启动类(根)加载器
3、扩展类加载器
4、应用程序加载器
5、双亲委派机制
沙箱安全机制
Native
PC寄存器
方法区
方法区放static、final、Class、常量池~
栈
堆
Heap,一个jvm只有一个堆内存,堆内存的大小是可以调节的。
类加载器读取了类文件后,一般会把什么东西放到堆中?类,方法,常量,变量,保存我们所有引用类型的真实对象;
java1.8以前:
java1.8以后:
GC垃圾回收,主要是在新生区和养老区
假设内存满了,OOM,堆内存不够!java.lang.OutOfMemoryError:java heap space
java1.8以后,永久存储区改名为元空间
堆内存中还要细分为三个区域:
- 新生区
类:诞生和成长的地方,甚至死亡;
伊甸园:所有对象都是在 伊甸园 区new 出来的
幸存者区(0,1):是伊甸园区轻GC存活下来的进入到幸存者区 - 养老区
在幸存者区(0,1)通过重GC存活下来的进入到养老区 - 永久区
这个区域常驻内存的。用来存放JDK自身携带的Class对象。Interface元数据,存储的是java运行时的一些环境或类信息,这个区域不存在垃圾回收!关闭JVM虚拟机就会释放这个区域的内存。
jdk1.6之前:永久代,常量池是在方法区;
jdk1.7:永久代,但慢慢的退化了,常量池在堆中;
jdk1.8之后:无永久代,常量池在元空间
元空间:逻辑上存在,物理上不存在
设置堆的大小 -XX:+PrintGCDetails输出GC相关的信息
使用JProfiler工具分析OOM原因
GC之复制算法
好处:没有内存的碎片
坏处:浪费了内存空间(幸存区to永远为空)
复制算法最佳使用场景:对象存活度较低的时候:新生区
标记清除算法
优点:不需要额外的空间
缺点:两次扫描,严重浪费时间,会产生内存碎片
压缩算法,用来优化标记清除算法
总结
内存效率:复制算法>标记清除算法>标记压缩算法(时间复杂度)
内存整齐度:复制算法=标记压缩算法>标记清除算法
内存利用率:标记压缩算法=标记清除算法>复制算法
GC:分代收集算法
年轻代:
- 存活率低
- 复制算法!
老年代
- 区域大:存活率
- 标记清除(内存碎片不是太多)+ 标记压缩混合 实现