作为JVM的一个组成部分,JVM堆是一个非常重要的一个部分,我们常说的JVM调优,一般调到就是堆内存,对于一个程序运行空间,堆内存是一个非常重要,也是最为复杂的的一个点。
我们一般看到的堆内存溢出,基本上都是老年代要炸了,抛出OOM的异常。
注:这里的永生代(方法区)在JDK1.8的时候,HotSpot设计者考虑到内存频繁被占满报OOM的问题,同时也是为了兼容HotSpot VM和JRockit VM(无永生代),就把永生代给替换成元空间了,元空间在本地内存,也就相当于,JVM里面的方法区在本地内存中。
对象的生命周期过程
新生代历经过程:
1.一个新的对象被实例化后,首先会放到Eden区域
2.当Eden区域满了之后,触发Minor GC(复制清除算法),存活下来的对象移到Survivor中的FromSpace中
3.FromSpace如果满了之后,触发Minor GC(复制清除算法),存活的对象又移到ToSpace中
4.当ToSpace满了之后,触发Minor GC(复制清除算法),存活的对象移到老年代。
老年代历经过程:
当老年代满了之后会触发Major GC=Full FC(标记清除算法),这个过程会清除老年代和新生代所有的线程全部处于等待,严重的会造成超时。
堆内存采用分代收集
根据对象的状态进行分类,GC回收扫描只针对固定区域进行扫描,减少了扫描的时间,不同的区域回收算法不一致,有利于提升回收的效率和质量。
垃圾回收算法
标记-清除算法:
GC分成俩个阶段,标记和清除,统一标记完成后再统一清除
缺点是:遇到大对象需要连续空间的话,又要触发GC进行清除
标记-整理算法:
也是分成俩个阶段,先统一标记,然后再统一整理,整理过后就会有一个边界,以这个边界,清除即可,这样就保证了连续空间分配的问题了。
复制-清除算法:
这个算法是把存活的对象从一块空间区域移到另外一个区域,然后留下的对象全部清除,这个同样也解决的空间的问题,不多多了区域之间的空间分配
垃圾收集器参数
参数 | 描述 |
-XX:+UseSerialGC | 串行收集器 |
-XX:+UseParallelGC | 并行收集器 |
-XX:+UseParallelGCThreads=8 | 并行收集器线程数,同时有多少个线程进行垃圾回收,一般与CPU数量相等 |
-XX:+UseParallelOldGC | 指定老年代为并行收集 |
-XX:+UseConcMarkSweepGC | CMS收集器(并发收集器) |
-XX:+UseCMSCompactAtFullCollection | 开启内存空间压缩和整理,防止过多内存碎片 |
-XX:CMSFullGCsBeforeCompaction=0 | 表示多少次Full GC后开始压缩和整理,0表示每次Full GC后立即执行压缩和整理 |
-XX:CMSInitiatingOccupancyFraction=80% | 表示老年代内存空间使用80%时开始执行CMS收集,防止过多的Full GC |
-XX:+UseG1GC | G1收集器 |
-XX:MaxTenuringThreshold=0 | 在年轻代经过几次GC后还存活,就进入老年代,0表示直接进入老年代 |
JVM参数设置的位置:
1、集成开发环境下启动并使用JVM,如eclipse需要修改根目录(不是安装目录)文件eclipse.ini;
2、集成开发环境下启动并使用JVM,如Idea需要修改Idea根目录(不是安装目录)下idea64.exe.vmoptions(64位系统)或者idea.exe.vmoptions(32位系统)
3、Windows服务器下安装版Tomcat,可使用Tomcat7w.exe工具(tomcat目录下)和直接修改注册表两种方式修改Jvm参数;
4、Windows服务器解压版Tomcat注册Windows服务,方法同上;
5、解压版本的Tomcat, 通过startup.bat启动tomcat加载配置的,在tomcat 的bin 下catalina.bat 文件内添加;
6、Linux服务器Tomcat设置JVM,修改TOMCAT_HOME/bin/catalina.sh;
jdk自带监控程序jvisualvm的使用: