jdk体系和jvm
自用。
同样的代码在不同的平台生成的机器码是不一样的,为什么java代码生成的字节码文件,能在不同的平台运行?
因为不同版本的jdk里面的虚拟机会屏蔽不同操作系统在底层硬件与指令上的区别。
栈:线程栈,局部变量存放栈内存区域。线程(分配一个栈)运行分配栈将局部变量放入内存。怎么放:栈帧。分配方法专属的内存区域(一个方法对应一个栈帧内存区域)。
程序计数器:存放线程运行当前代码的位置(由字节码执行引擎去记录),是为了线程切换,该线程的CPU被其他线程抢走,挂起,记录执行位置。
方法出口:应该回到Main方法的哪个位置去
本地方法栈:老年方法的调用(xx.dll)以及现如今的框架等等的接口的调用,调用到本地方法,就会有本地方法栈
堆:分为Eden区、Survivor区、老年代区。
方法区(元空间):常量+静态变量+类信息
GCroots:找静态变量、局部变量的引用链对象,不是垃圾对象放入Survivor区
分代年龄:一次GC+1,当到了15就放入老年代,如:静态变量,缓存,线程池,Spring的BEAN容器中的对象
minor gc
full gc: 老年代满了后,做full gc,尝试收集整个堆的垃圾对象,如果收集不了,就OOM
STW:stop the world,GC时把线程给停掉。
案例分析:
线上系统jvm调优
多台机器,300单/秒,每个1KB,300KB放入堆内存,放大20倍,每秒要有6M对象生成->每秒60M对象生成,1秒后都变成垃圾对象,
分配给虚拟机4-5个G,方法区类多的话分配512M内存,栈开1000个线程,一个1M,
此时13秒回占满eden,但是最后一个60M对象不会被minor gc释放,会放入S0,根据动态年龄判断(如果对象大小大于S区的50%),会直接放入OLD区,这样old区会在几分钟后放满,执行full gc,
调优如下