jvm gc

jvm 内存的分配

方法区: 类加载到jvm中开辟的内存保存类的结构信息,类字段初始化的变量的值;
方法区的实现: jdk1.7 永久代
              jdk1.8 metaspace元数据空间  -->permanent space


堆内存:创建对象保存的地方; 
堆内存的实现: old generation + eden + surviver0 + survivo1


线程独占的内存: 虚拟机栈;

程序计数器: 程序执行的指令执行到的位置;

虚拟机栈: 局部变量列表, 操作数栈,动态连接,返回地址;
方法入栈的过程大概如下:局部变量进入操作数栈, 弹栈 ,局部变量列表添加一个变量复制为操作数栈弹栈的值;
方法内部调用方法的时候会继续另外一个方法的入栈(虚拟机栈), 是是更加动态连接在方法区寻找到对应的方法进行执行,如果有返回值;
那么进行返回值进入操作数栈 , 弹栈 , 变量交给动态链表记录到执行的结果;
操作数栈扮演者数据计算的中间的一个内存提供, 参与计算的变量需要首先进入到操作数栈; 得到的结果会交给局部变量列表;

虚拟机内存

jvm gc

对象创建的时候会向eden申请内存空间来储存, 如果发现eden区域的内存不够的时候会进行一次minor gc;

minor gc怎么做的呢?
首先对eden区域的内存进行标记清理,对存活的对象复制到survivo0, 下次minor gc 的时候对survivo0区域的内存进行标记清理,将存活的对象
放到survivo1中去 这样反复的进行;

1.每次minor gc的时候 存活的对象的年龄都会增加1; 如果年龄增加到一个阈值(-XX:MaxTenrningThreshold)
默认为8 的时候会进行内存的提升,提升到永久代; 

2.还有一种情况是在survivo区域内相同的年龄的存活的对象大小的总和大于了survivo内存大小的
一半的时候, 那些存活年龄大于或者等于该年龄的对象会被提升到永久代,无需年龄达到阈值;

full gc触发的条件
系统调用了system.gc() , 系统建议执行full gc 但是不一定要执行;
perm space 内存不足的时候;
方法区空间不足的时候;
minor gc 内存进行提升后到值永久代的时候内存不够(需要查看HandlePromotionFailure是否允许 如果允许那么只会进行一次minor gc; 
否则进行一次full gc;)

full gc 是通过垃圾的整理进行垃圾回收的, 因为老年代的垃圾回收的几率太低了, 复制所有的对象是消耗性能的;
jdk1.8不在会有"java.lang.OutOfMemoryError:PerGen space"; 
修改永久代的参数为 -XX:MetaspaceSize  和 -XX:MaxMetaspaceSize


堆内存的设置:-XX:Xmx20M  -XX:Xms20M 
-XX:Xmn10M 年轻代


Serial Garbage Collector : 串行垃圾回收器
Parallel Garbage Collector:并行垃圾回收器 default
CMS Garbage Collector: concurrent mark sweep 并发标记清理垃圾回收器; 使用-XX:+UseParNewGCJVM参数来开启使用CMS垃圾回收器。
G1 Garbage Collector:G1垃圾回收器应用于大的堆内存空间。它将堆内存空间划分为不同的区域,对各个区域并行地做回收工作
使用-XX:UseG1GCJVM参数来开启使用G1垃圾回收器

eclipse 调优

-verbose:gc
-XX:+PrintGCDetails
-XX:+PrintGCDateStamps
-Xloggc:D:/dev/sts-3.9.0.RELEASE/gc.log
-Xms512m
-Xmx1024m
-XX:NewSize=256m
-XX:MaxNewSize=256m
-XX:PermSize=96m
-XX:MaxPermSize=96m
-XX:+DisableExplicitGC
-XX:CompileThreshold=100
-Xverify:none
-XX:+UseParNewGC
-XX:+UseConcMarkSweepGC
-XX:CMSInitiatingOccupancyFraction=80