首页 理论教育 现有内存管理机制的优化

现有内存管理机制的优化

时间:2023-06-29 理论教育 版权反馈
【摘要】:即引进新的Tung-sten内存管理机制的主要原因在于优化JVM在内存方面和GC方面的开销。另外在JVM内存模型中,为了更加通用,它重新定制了自己的储存机制,使用UTF-16方式编码每个字符(2字节)。GC的开销在所有基于JVM的应用程序中都是不可忽视的,而且对应的调优也非常繁琐,在类似Spark框架这样的基于内存迭代处理的框架中,通常直接在底层对内存进行管理可以极大地提高效率。

现有内存管理机制的优化

Spark计算框架是基于Scala与Java语言开发的,其底层都使用了JVM。而在JVM上运行的应用程序是依赖JVM的垃圾回收机制来管理内存的,随着Spark应用程序性能的不断提升,JVM对象和GC开销产生的影响(包括内存不足、频繁GC或FullGC)将非常致命。即引进新的Tung-sten内存管理机制的主要原因在于优化JVM在内存方面和GC方面的开销。主要包含两个方面。

1.JVM对象模型(JVM object model)的内存开销

可以通过Java Object Layout工具来查看在JVM上Java对象所占用的内存空间(有兴趣的读者可以参考http://openjdk.java.net/projects/code-tools/jol/),需要注意的是在32位与64位的操作系统中,占用空间会有所差异,下面是在64位操作系统上对String的分析结果。

一个简单的String对象会额外占用一个12字节的header和8字节的hash信息。这是开启(-XX:+UseCompressedOops,默认)指针压缩方式(-XX:+UseCompressedOops)的结果,如果不开启(-XX:+UseCompressedOops)指针压缩(-XX:+UseCompressedOops),则内存更大,如下所示。

其中,Header会占用16个字节的大小,另外JVM内存模型会采用8字节对齐,因此也可能会再增加一部分内存开销。

以上仅仅是String对象中JVM内存模型中占用的内存大小,实际计算时需要考虑其内部的引用对象所占的内存,通过分析,char[]中默认的指针压缩情况下会占用16bytes内存,因此仅仅是一个空字符串也会占用2440bytes+1640bytes=4 Kbytes的内存。(www.xing528.com)

另外在JVM内存模型中,为了更加通用,它重新定制了自己的储存机制,使用UTF-16方式编码每个字符(2字节)。可以参考http://www.javaworld.com/article/2077408/core-java/sizeof-for-java.html,java对象的内存占用大小,如下所示。

其中CHAR FIELD SIZE为2,即每个字符串在JVM中采用了UTF-16编码,一个字符会占用两个字节。

2.垃圾回收机制(Garbage collection,GC)的开销

JVM对象带来的另一个问题是GC。通常情况下,JVM内存模型中的Heap会分成两大块:Young Generation(年轻代)和Old Generation(年老代),其中年轻代会有很高的allocation/deallocation,通过利用年轻代对象的瞬时特性,垃圾收集器可以更有效率地对其进行管理;年老代的状态则非常稳定。GC的开销在所有基于JVM的应用程序中都是不可忽视的,而且对应的调优也非常繁琐,在类似Spark框架这样的基于内存迭代处理的框架中,通常直接在底层对内存进行管理可以极大地提高效率。因此,对应引入Project Tung-sten也就很合情合理了。

下面的章节会详细解析Project Tungsten的内存模型及其源代码实现,并且对基于该模型的Shuffle写数据过程中的二进制数据处理也给出了详细解析。

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

我要反馈