[TOC]
java虚拟机
内存分配
运行时数据区
线程私有的:程序计数器:指向当前线程正在执行的字节码指令的地址(行号)
java是多线程的,意味着线程切换
确保多线程情况下的程序正常执行
运行时数据区
栈,是一个数据结构, FILO first in last out
虚拟机栈(深度 -Xss )
存储当前线程运行的方法所需的数据,指令,返回地址
- 栈帧:有一个局部变量表,操作树栈,动态连接,返回地址
javap -v JavaStack.classs 反编译
java字节码指令大全- 局部变量表:
- 操作数栈
- 动态连接
动态代码, js 运行时编译
java多态 - 程序计数器,会不会报内存溢出? 答:不会,只是简简单单计个数
虚拟机栈溢出 始终调用不到return,就会出现这个错误
StackOverflowError
执行的虚拟机栈深度大于虚拟机栈运行最多的栈的深度
如何处理?
- 栈帧:有一个局部变量表,操作树栈,动态连接,返回地址
方法区
类信息, 常量池(常量) ,静态变量,即时编译期编译后的代码(动态运行时编译)
java堆
对象实例, 数组深入理解JMM(jvm的内存模型)
对象是有什么周期的
jvm中的垃圾回收机制
垃圾回收的依据
- 可达性分析算法
在java中,可作为GC Roots的对象包括:
- 虚拟栈(本地变量表)
- 方法区:类静态属性引用的对象
- 方法区:常量引用的对象
- 可达性分析算法
jvm内存分配规律
jmm内存模型的话,
堆 : 新生代,老年代
方法区:永久代(元空间)大对象直接进入老年代
对象优先进入eden
长期存活的对象将进入老年代 age=15 (一次gc,新生代中发生)
动态年龄对象判断,
空间分配担保 ;老年代有足够的空间可以存放
新生代:minor GC 复制回收算法 (新时代(8:1:1) 90%的对象不需要回收,10%的对象需要回收,所以用了2个10%) 存活概率低,所以使用这个方法
复制回收算法:可用内存,看回收内存,存活对象 保留对象
复制算法:一般只用一半老年代: Full GC (性能比较消耗,回收效率比较低) 标记-清除算法,标志整理算法
标记-清除算法:然后会出现内存碎片
所以当内存碎片多的时候,出现 标记-整理算法标记-整理算法:整理后就没有内存碎片
永久代:会不会进行垃圾回收?也会,回收率非常低
交换区间里面就是赋值回收算法
虚拟机栈为什么没有回收
- 栈跟线程生命周期相关的
堆是垃圾回收的重点区域
GC的发展趋势
jdk 11中的ZGC - 一种可扩展的低延迟垃圾收集器
处理TB量级的堆(8g g1垃圾收集器)
gc时间不超过10ms (Full gc JVM会全部停止)
与使用gc的应用吞吐量降低不超过15% gc 也消耗程序的吞吐量
jvm常用问题解决
1.内存泄漏, 始终有个gc roots的应用,而程序业务上没有使用
应用计数法
solid 最小知识原则- 垃圾回收
PermGen: 永久代