java virtual machine (java虚拟机)
- 堆,线程栈,本地方法栈,方法区(元空间),程序计数器
- 局部变量会存放在线程栈内存中,有栈帧组成,先进后出,栈帧由局部变量表,操作数栈,动态链接,方法出口
- 程序计数器是线程独有的,是记录当前线程运行的代码的位置,字节码执行引擎动态修改程序计数器的值,(为什么要有程序计数器?线程切换的时候,切回来的时候可以知道继续运行当前的代码)
- 操作数栈它是一块临时的内存区域,存放临时的操作数
- 方法出口也是一块内存区域,记录方法执行完需要回到的代码的位置
- 堆里面的对象和局部变量表中的对象的关系,存放的对象的引用地址
- **方法区存放的是常量+静态变量+类信息,静态对象变量存储的也是对象在堆中的引用地址,jdk1.8 之前叫永久代,之后叫元空间 **
- 本地方法栈:native 修饰,本地方法接口,底层是C语言实现的,本地方法运行的时候需要的一块内存区域
堆内存区
-
年轻代占 1/3 老年代占2/3 eden区占8/10 survivor占2/10
-
minor gc 收集eden区的垃圾,将未能清理复制到survivor区,复制算法,如果没有被垃圾回收,分代年龄,在对象头上存储,每次加1;再次回收的时候也会回收会回收survivor区和eden区,当通过多次垃圾回收之后,分代年龄达到15的时候警徽移动到老年代。大对象会直接移动到老年代。线程池中的对象,静态变量,缓存对象,springbean对象会到老年代,老年代存放满的时候会怎么办?会做一个FULL GC(STOP THE WORLD,把用户的应用线程停掉,),虚拟机调优就是要减少FULL GC的次数,减少FULL GC的时间。minor_gc 也会stop the world 但是时间很短,可以忽略不计。
-
可达性垃圾收集。可达性分析算法 。GCROOT根节点:线程栈的本地变量,静态变量,本地方法栈的变量等等 ;GC ROOT 对象作为起点,从这些节点开始向下搜索引用的对象,找到的对象都标记为为垃圾对象,其余为标记的对象都是垃圾对象
-
安装jdk的可以通过jvisualvm 需要安装 visual gc 插件
-
JVM 调优:
-
对象动态年龄判断:如果survior 区超过百分之五十,会直接移动到老年代。对虚拟机进行优化,几乎不发生FULL GC 让年轻代分配的内存大一点,对年轻代的内存大一些。-Xmn=2048M 指的是分配给年轻代2个G ,老年代相对可以小一点