一、jvm中类的创建过程
加载->验证->准备->解析->初始化->使用
1,加载:
在硬盘上查找并通过IO读入字节码文件,把class常量池中的内容存放到方法区的运行时常量池中, 类信息存放到方法区(比如静态变量的引用,字段信息,方法信息,类加载器的引用以及对应class实例的引用)
2,验证:
校验字节码文件的正确性
3,准备:
给类的静态变量分配内存,并赋予默认值
4,解析:
将符号引用替换为直接引用,该阶段会把一些静态方法(符号引用,比如main()方法)替换为指向数据所存内存的指针或句柄等(直接引用)
5,初始化:
对类的静态变量初始化为指定的值,执行静态代码块
二、jvm中对象的创建过程
1,检查类是否已加载
虚拟机遇到一条new指令时,首先将去检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否已被加载、解析和初始化过。
如果没有,那必须先执行相应的类加载过程。
2,初始化内存
在分配内存时,分为指针碰撞和空闲列表
解决分配时的并发问题的方法:1,cas,锁争抢 2,本地线程分配缓存
3,设置对象头
对象内存分布:对象头 +实例数据+对齐填充
对象头分为两部分:mark word+指针引用+数组长度(只有数组才有)mark word:(hash,Gc分代年龄,锁状态标志等)
指针引用(确定这个对象是哪个类的实例)4,初始化
三、jvm内存模型
- 虚拟机采用了分代收集的思想来管理内存,一般将java堆分为年轻代和老年代
垃圾回收过程
1,年轻代包括eden区,两个交换区,我们称为survivor区。
2,大量的对象被分配在eden区,eden区满了后会触发minor gc,通过可达性分析算法之后,大部分的对象会被标记为垃圾对象,被回收掉。
剩余存活的对象如果满足Survivor区容纳大小的话,将通过复制算法,被复制到为空的那块survivor区,并将对象年龄设为1。
下一次eden区满了后又会触发minor gc,把eden区和不为空的survivor区垃圾对象回收,把剩余存活的对象又通过复制算法,全部挪动到另外一块为空的survivor区,之后会重复相同的操作。
3,不断在交换区进行交互复制。对象在 Survivor 中每熬过一次 MinorGC,年龄就增加1岁,当它的年龄增加到一定程度就会被晋升到老年代中(默认为15岁,CMS收集器默认6岁,不同的垃圾收集器会略微有点不同)。
4,老年代,满了后,会触发full gc。通常为标记-整理算法进行垃圾回收。
这里面jvm判断对象是否为垃圾对象时通过可达性分析算法
四、可达性分析算法
将“GC Roots” 对象作为起点,从这些节点开始向下搜索引用的对象,找到的对象都标记为非垃圾对象,其余未标记的对象都是垃圾对象。
GC Roots根节点:线程栈的本地变量、静态变量、本地方法栈的变量等等
常见引用类型 java的引用类型一般分为四种:强引用、软引用、弱引用、虚引用
即使在可达性分析算法中不可达的对象,也并非是“非死不可”的,这时候它们暂时处于“缓刑”阶段,要真正宣告一个对象死亡,至少要经历再次标记过程。
五、垃圾收集器
要点理解:
1,垃圾收集算法:标记-清理,标记整理,标记-复制
标记-清理会产生浮动垃圾,标记复制:不适合大对象和多对象情景(所以年轻代垃圾回收用复制算法,老年代多用复制-整理算法)
2,cms的优缺点
优点:
对stw时间有要求,可以使用并发垃圾收集,
缺点
有浮点垃圾
在使用的时候,可能自动切换成serilold垃圾搜集算法3,G1和cms的区别
g1可以手动控制stw时间
六、jvm调优
理解含义:-Xms1536M -Xmx1536M -Xmn512M -Xss256K 分别值:初始内存,最大内存,年轻代内存大小,线程大小
1 Jvisualvm
有时候,系统启动和反应很慢,就会通过jvisualvm命令查看年轻代和老年代存储情况,调整jvm各代内存大小来提升性能。
查看堆运行参数
jmap -heap {id}
查看内存
jmap -histo {id}
2 分析系统的垃圾回收情况
通过jstat -gc {pid} {time} {count}
3 Top
通过top命令看资源占用情况,对于占用高的进程。通过top -Hp pid查看该进程下线程哪个高。
最后通过jstack pid|grep -A 10 742查看队栈状态(724为pid转16进制后的值)