jvm内存结构
1、程序计数器:几乎不占内存,用于取吓一条指令
2、堆:所有通过new创建的对象内存都在堆中分配
3、栈:每个线程在执行每个方法时都会申请一个栈帧,每个栈帧包括局部变量区和操作数栈,用于存放此次方法调用过程中的临时变量、参数、中间结果
4、本地方法栈:存储每个native方法调用的状态
5、方法区:用于存放类信息、静态变量、final常量、属性和方法信息,jvm用永久代存放
什么是新生代
1、新生代由eden区、from survivor区和to suivivor区组成,内存占比默认为80%、10%、10%
2、新建的对象都由新生代分配内存,eden空间不足时,会把存活的对象转移到survivor
3、新生代由于存活时间短,所以GC比较频繁
什么是老年代
1、用于存放在新生代多次回收依然存在的对象
2、新生代经过一次minorGC后,如果对象还存活,并且能够被另一块survivor内存所容纳,则使用复制算法把这些依旧存活的对象复制到另一块survivor中,然后清理eden和第一块survivor区域,同时将这些对象的年龄设置为1,之后survivor区域每熬过一次minorGC,就将这些对象的年龄加1,当对象的年龄达到某个值(默认15)后,这些对象就会成为老年代
3、对于一些较大的对象,直接进入老年代。比如对象大小超过eden空间或者survivor空间。或者对象比较大,为了避免eden到survivor端的大量复制,提前进入老年代
新生代和老年代在jvm中的内存空间占用比例分配
新生代1/3,老年代2/3
eden和from survivor、to survivor在内存中的空间占用比例
eden80%,from survivor 10%,to survivor 10%
新生代的回收算法
复制算法:扫描出存活的对象,然后复制到一块新的完全未使用的空间中。对应于新生代:就是在Eden和其中一个Survivor,复制到另一个之间Survivor空间中,然后清理掉原来就是在Eden和其中一个Survivor中的对象。
老年代的回收算法
标记-清除算法:对没有引用,需要回收的对象进行标记,然后统一回收
缺点:效率问题;空间问题
什么是minorGC
Minor GC 是发生在新生代中的垃圾收集动作,所采用的是复制算法:
什么是fullGC
Full GC 是发生在老年代的垃圾收集动作,所采用的是标记-清除算法:
jvm内存清理过程
用javavisualVM来查看,能明显观察到新生代满了后,会把对象转移到旧生代,然后清空继续装载,当旧生代也满了后,就会报outofmemory的异常。
jvm参数
-Xms 初始堆大小。如:-Xms256m
-Xmx 最大堆大小。如:-Xmx512m
-Xmn 新生代大小。通常为 Xmx 的 1/3 或 1/4。新生代 = Eden + 2 个 Survivor 空间。实际可用空间为 = Eden + 1 个 Survivor,即 90%
-Xss JDK1.5+ 每个线程堆栈大小为 1M,一般来说如果栈不是很深的话, 1M 是绝对够用了的。
-XX:NewRatio 新生代与老年代的比例,如
–XX:NewRatio=2,则新生代占整个堆空间的1/3,老年代占2/3
-XX:SurvivorRatio 新生代中 Eden 与 Survivor 的比值。默认值为 8。即 Eden 占新生代空间的 8/10,另外两个 Survivor 各占 1/10
-XX:PermSize 永久代(方法区)的初始大小
-XX:MaxPermSize 永久代(方法区)的最大值
-XX:+PrintGCDetails 打印 GC 信息
-XX:+HeapDumpOnOutOfMemoryError 让虚拟机在发生内存溢出时 Dump 出当前的内存堆转储快照,以便分