Java虚拟机垃圾回收调优
来源:互联网 发布:潘多拉优化中心 编辑:程序博客网 时间:2024/06/04 23:18
GC对性能的影响在于,如果内存中数据量比较大的话,那么可能会造成GC频繁的发生,另外如果要回收的数据量特别大,那么会导致GC的速度也比较慢。gc线程工作时,会让程序中的task线程暂停工作,那么整个应用程序的性能就会大打折扣。
对于Spark应用程序可以从以下几个方面来优化。
1、优化executor内存比例
对于垃圾回收来说,最重要的就是调节RDD缓存占用的内存空间,与算子执行时创建对象占用的内存比例。默认情况下,Spark使用每个executor 60%的内存空间来缓存RDD,那么task执行期间创建的对象,只有40%的内存空间来存放。
这种情况下,很有可能因为内存空间不足,task创建的对象过大,一旦发现40%的内存空间不够用了,就会触发虚拟机的垃圾回收操作,频繁的GC会极大降低程序的整体性能。
这个时候就需要对这个比例进行调优,使用SparkContext.set("spark.storage.memoryFraction","0.5")即可,这样就提高了创建对象所用的内存。
对于RDD的缓存,可以用Kryo序列化,加上降低其executor内存占比方式,来减少其内存消耗。给task提供更多的内存,从而避免task的执行频繁触发GC。
2、高级垃圾回收调优
Java堆空间被分成两块空间,一个是年轻代,一个是老年代。年轻代放的是短时间存活的对象,老年代放的是长时间存活的对象。年轻代又划分成了三块空间,Eden、Survivor1、Survivor2。
创建对象时,首先放入Eden区域和Survivor1区域,如果Eden区域满了,那么就会触发一次MinorGC,进行年轻代垃圾回收。此区域中存活的对象会被移到Survivor2区域中,然后Survivor1和Survivor2角色调换,Survivor1成了备用。
如果一个对象,在年轻代中,撑过了多次垃圾回收,都没有被回收掉,那么会被认为是长时间存活的,此时就会被移入老年代。此外,如果在将Eden和Survivor1的存活对象,尝试放到Survivor2中时,发现Survivor1满了,那么会直接放入老年代。此时很快就会将老年代内存撑满,从而发生full gc。full gc要回收大量的短时间存活的对象,会导致速度很缓慢。此时可以执行一些操作来优化垃圾回收行为:
1)给年轻代分配更大的空间,使用-XX:NewRatio=n(n为年轻代与老年代的比值)
2)给Eden区域分配更大的内存,使用-XX:SurvivorRatio=n(n为年轻代中Eden区与Survivor区的大小比值)
3)-Xmn=20g,这个参数可以直接指定年轻代内存大小
4)使用吞吐量优先的并行收集器。
-XX:+UseParallelGC:选择年轻代垃圾收集器为并行收集器,即MinorGC
-XX:ParallelGCThreads:配置并行收集器的线程数,有多少处理器就多少线程
-XX:+UseParallelOldGC:配置年老代垃圾收集方式为并行收集
- Java虚拟机垃圾回收调优
- java虚拟机------垃圾回收
- Java虚拟机垃圾回收
- java虚拟机-垃圾回收
- java虚拟机垃圾回收
- Java虚拟机垃圾回收
- java虚拟机垃圾回收
- Java SE 6 Hotspot [TM] 虚拟机垃圾回收调优
- Java SE 6 Hotspot 虚拟机垃圾回收调优
- Java -- Hotspot虚拟机调优与GC垃圾回收策略
- Java SE 6 Hotspot 虚拟机垃圾回收调优
- Java虚拟机垃圾回收(四) 总结:内存分配与回收策略 方法区垃圾回收 以及 JVM垃圾回收的调优方法
- java虚拟机垃圾回收机制
- java虚拟机垃圾回收机制
- java虚拟机之垃圾回收
- java虚拟机垃圾回收机制
- Java虚拟机之垃圾回收
- Java虚拟机之垃圾回收
- mysql中某个字段中其中一个字符出现的次数
- 每日一题——求二叉树的高度,销毁二叉树
- 关于call与apply的前世今生
- [hdu 1260] Tickets [DP]
- 文章标题
- Java虚拟机垃圾回收调优
- Linux设备驱动编程之内存与I/O操作
- Android之创建定时任务
- 扫雷JavaSE+控制台
- MUI框架默认全局不可复制
- 线段树_初步
- stm32串口发送16进制字符和16进制数的区别和具体实现方法
- 阿里Druid
- 仿IOS效果-ToggleButton