程序计数器:线程私有,当前线程所执行的字节码的行号指令集。
虚拟机栈:线程私有,方法执行的动态内存模型,一个方法被执行的时候会创建栈帧,栈帧里记录的是局部变量表、操作帧、动态链接、方法出口等信息,一个方法被执行到结束的过程,就是栈帧入栈出栈的过程。
本地方法栈:线程私有,与虚拟机栈相同,区别是所服务的方法是Native方法。
方法区:线程共享,存储加载的类信息、常量、静态常量等。
堆:线程共享,存放对象实例。除了逃逸分析技术(栈上分配、标量替换)产生的对象,几乎都存放在堆中。
虚拟机栈溢出:创建大量的线程、递归算法
堆溢出:创建大对象、对象生命周期过长、存储结构设计不合理、
如果没有Survivor,Eden区每进行一次Minor GC,存活的对象就会被送到老年代。老年代很快被填满,触发Major GC.老年代的内存空间远大于新生代,进行一次Full GC消耗的时间比Minor GC长得多,所以需要分为Eden和Survivor。
Survivor的意义,就是减少被送到老年代的对象,减少Full GC的发生,Survivor的保证只有经历15次Minor GC还能在新生代中存活的对象,才会被送到老年代。
设置两个Survivor区最大的好处就是解决了碎片化,刚刚新建的对象在Eden中,经历一次Minor GC,Eden中的存活对象就会被移动到第一块S0区,Eden被清空;等Eden区再满了,就再触发一次Minor GC,Eden和S0中的存活对象又会被复制送入S1(这种复制算法保证了S1中来自S0和Eden两部分的存活对象占用连续的内存空间,避免了碎片化的发生)
新产生的对象被分配到Eden 区。
当 Eden 区的空间满了, Java虚拟机会触发一次 Minor GC,收集新生代的垃圾,存活下来的对象会转移到 Survivor区。
大对象直接进入老年态;
如果Eden的对象,经过第一次Minor GC后仍然存活,并且被移动到Survivor区,标识设为1,每经过一次Minor GC,标识+1,若标识超过一定限制(默认为15),则被晋升到老年态。即长期存活的对象进入老年态。
老年代满了而无法容纳更多的对象,Minor GC 之后通常就会进行Full GC,Full GC 清理整个内存堆 – 包括年轻代和年老代。
Major GC 发生在老年代的GC,清理老年区,经常会伴随至少一次Minor GC,比Minor GC慢10倍以上。
Serial收集器:单线程新生代垃圾收集器。
Serial Old收集器:Serial老年代收集器,也与Parallel Scavenge收集器搭配。
ParNew收集器:并行收集的多线程新生代收集器,标记-复制算法。关注用户停顿时间
Parallel Scavenge收集器:并行收集的多线程新生代收集器,标记-复制算法。关注垃圾收集的吞吐量。
Parallel Old收集器:Parallel Scavenge收集器
CMS收集器:老年代收集器。标记-清除算法,内存碎片化。无法清理浮动垃圾。当内存不足时,触发Concurrent Mode Failure,启动Serial Old收集器。
G1收集器:堆内存区域进一步划分,分为多块Region区。每块Region区都要维护自己Region区的记忆集。对于大对象有专门的Region区。并发标记阶段使用快照方式,不影响用户线程。通过停顿预测模型来进行垃圾收集。
对象优先分配在Eden区
大对象直接分配在老年区
长期存过(经过15次Minor GC)的对象进入老年区
空间分配担保
根据new对象的参数在常量池用定位一个类引号的引用
如果没有,说明类怎么没加载,进行类的验证,加载,解析和初始化
为对象在堆中分配内存
将分配到内存的对象静态变量、属性初始化为零值。(常量已经在常量池中)
调用类的方法进行参数赋值
强引用:主要引用还在,垃圾收集器就不会回收
软引用:在内存发生溢出之前,进行回收
弱引用:下次进行垃圾收集时回收
虚引用:随时进行回收
你适合学Java吗?4大专业测评方法
代码逻辑 吸收能力 技术学习能力 综合素质
先测评确定适合在学习