storage memory是什么意思,如何计算得出的

SparkUI的Executor页面上有个storage memory指标,好奇这个指标的数值代表什么含义,是如何被精确计算的

storage memory,虽然名字看起来是存储内存的大小,但实际上由于spark1.6之后已经实现了统一内存管理(即执行内存和存储内存使用同一个统一内存),所以storage memory实际上是统一内存的大小,是sparkSQL中我们设置spark.executor.memory和spark.memory.fraction,在jvm中能够被用来计算和存储的内存。如下图红圈部分是storage memory的范围。

以下面参数设置为例

SET spark.executor.memory=1792M;
SET spark.memory.fraction=0.6;

按照上图的结构,可以得出storage memory=(spark.executor.memory-300)*spark.memory.fraction=(1792-300)*0.6=895.2,这个数值和sparkui上的775.8是有不小的差距的。

深入研究后发现,实际上jvm的堆内存管理存在YoungGen(新生代)和OldGen(老年代),而YoungGen又分为Eden、From(s0) 和 To(s1) 区,我们设置的参数spark.executor.memory实际作用在jvm上,只有OldGen+Eden+From部分的内存是可以用来真实存储数据的,To只是用来GC时暂存幸存的数据。关于jvm的内存管理是另一个比较大的话题,就不在这里展开了。

通过设置spark.executor/driver.extraJavaOptions=-XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintHeapAtGC,可以在stdout中看到gc的日志,也可以看到新wden、from、to、oldgen的大小。

SET spark.executor.extraJavaOptions=-XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintHeapAtGC;

SET spark.driver.extraJavaOptions=-XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintHeapAtGC;

但是查看GC日志发现,oldgen的内存大小是固定的,但是eden、from和to的大小是动态变化的。查阅资料发现,目前使用的jdk是1.8,默认使用了 UseParallelGC 垃圾回收器,该垃圾回收器默认启动了 AdaptiveSizePolicy(自适应大小策略),会根据GC的情况动态的计算 Eden、From 和 To 区的大小;所以在GC日志里的各个区域内存大小是动态改变的。sparkUI上显示的内存大小是如何在动态环境下计算得出一个固定值不得而知,所以也很难根据GC日志算出775.8M这个数值。

我们尝试通过设置-XX:-UseAdaptiveSizePolicy关闭自适应大小,来看看效果

关闭后,storage memory变为了850.5MiB,GC日志中新生代的实际可用内存也不再变化

此时我们可以算一下,eden+from+oldgen=458752+76288+1223680=1758720kib

storage memory=(1758720/1024-300)*0.6=(1717.5-300)*0.6=1417.5*0.6=850.5

可以说是一点都不差!

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值