一、栈,堆
1.栈帧:方法每次调用都会新建一个栈帧并将其压栈到栈顶。方法结束(正常结束或者抛出未捕获的异常)即销毁。类似作用域。
2.栈:存放基本数据类型,变量
3.堆:存放new 出来的对象(实例,数组)
4.方法区(又称静态区):存放class信息和static 变量
关于StackOverFlowError和OutOfMemoryError
ps:
若当前线程请求(栈帧堆满栈)超过配置的范围,就会抛出StackOverFlowError(eg:递归调用,方法重复调用,新建的栈帧增多,一直没有出栈)
public static void testStackOverFlow(){
for(;;)
testStackOverFlow();
}
OutOfMemoryError:
①栈内存溢出(-Xss)
需要新的栈帧,但没有足够内存可分配
②堆内存溢出(-Xms)
创建实例需要分配空间,没有足够内存可用
③方法区内存溢出(-XX:MaxPermSize)
类加载时要存储类信息,没有足够空间
二、GC
1.堆的分区(分区是为了优化GC性能)
①年轻代
又分为2个Survivor区域和1个Eden区域 默认比例 1:8
原因分析:一般情况,新创建对象会被分配到Eden区(一些大的对象特殊处理),经过Minor GC处理后,若仍存活,会被移到Survivor区。
②老年代
年轻代转移到老年代的情况:
1)大对象
2)长期存活的对象
3)经过Minor GC处理后 仍然放不下
4)动态年龄判断
在Survivor区每经过一次Minor GC处理若存活,年龄增加一岁。大于等于某个年龄的对象超过了survivor区一半,这些对象会直接进入老年代
2.GC 分类
①Minor GC 回收年轻代
触发情况:eden区内存不足。JVM回收涉及到根搜索算法。JAVA对象的关联关系其实就是根到节点的关系,从根开始遍历至叶子节点,死掉的对象会和根断掉关系,没死掉的对象会由Minor GC强制断开关系
②Major GC 回收老年代
③Full GC 清理整个堆空间