从java到大数据的内存进化

内存管理一直时计算机系统演进一个重要的指标。从最初的单任务,到后来的多任务置换,再到页式内存管理以及段页式管理。每一次变更都对计算机计算性能有很大的提升。同样在大数据计算领域,内存的管理一直是提升计算性能的重要调优热点。无论分布式系统还是java,在内存管理上一致跟随着操作系统在内存管理设计。

今天先说说Java的内存管理:

“天下大势,分久必合,合久必分!”这句话来形容Java的内存管理很是贴切。Java的内存大致可以分为几块:栈,堆,方法区,其他。在Jvm规范中声明这些内存区域可以是连续的,也可以是不连续的。这其中变化最大,且对性能影响较大的区就是堆区了。而堆区的变化有和垃圾回收有很大的关系。

可能大多数的初学者和我以前一样都有一个疑惑,为什么Java会去简求繁把对内存划分成这么多的区。一个直观地想法就是这样做可以提升计算性能,但是到底是从那个方向解决的性能问题,又解决了什么问题。众所周知,垃圾回收是Java的一大特性,可以减轻程序员在开发过程中的负荷,不用担心因为内存没有即时的释放导致内存泄漏。早期版本的垃圾回阶段需要停顿所有的工作线程,扫描整个堆区进行垃圾回收的工作。这样就导致java无法满足高响应请求的要求,为了减少由于垃圾回收所导致的系统抖动(工作线程停顿)对计算性能的影响。java的堆区就被人为的划分成多个块(新生代,s1区,s2区,老年代),每个堆区放置不同类型的对象,不同堆区针对存放数据的不同使用不同垃圾回收机制。每次垃圾回收只扫描相应的区,不用扫描全部堆区,这样就可以把垃圾回收导致的系统抖动降低到最小。至此,我们了解到java堆分区是为了解决垃圾回收过程中所遇到的问题。

划分不同堆区,虽然减少了GC过程中对工作现成的影响。但是堆内存却出现了隔离,比如:如果设置不合理可能会导致新生代数据满了后,老年代还有很多空间,新生代却不能占用老年代的的空间。只能通过垃圾回收释放资源,或者将新生代的老对象移到老年代才能继续分配新生代对象。还有可能导致老年代空间满了但是新生代还有许多空间。内存空间的利用就会成为一个瓶颈。即使改进之后的新生代调整了s1,s2区的比例,内存利用率依然是一个瓶颈。

基于这些困扰,sun在2004年发布第一篇关于《G1》的论文,这是一种新的GC方式。伴随着变化的是堆区的分配也跟着被重构。历时7年第一个商用版本在2011年发布。连续堆块变成了大小相同的内存片region(可以配置1M,2M,4M,16M..)。不再有新生代和老年代空间的绝对隔阂,替代的是新生代和老年代内存列表,也就意味着新生代的内存空间不再是连续的。在GC过程中不再需要扫描整个连续区,只需要搜索标记每个regon块中垃圾空间大小。然后链表按照可回收空间大小排序,优先回收可回收空间比较大regon,这样GC的时间就可控。可以控制GC时间和GC空间做权衡,再指定时间最大效率回收内存。

基于此,大家可以发现JVM内存管理和操作系统的内存管理进化历程类似,一开始是单用户,再多多用户,再到页式内存管理,再到段式以及段页式内存管理。磁盘碎片和内存碎片再jvm中同样会遇到,两者采用的处理方式也类似。比如空闲链表,内存兑换区等等。

再大数据领域,同样也在经历类似的进化。在资源管理方向,从hadoop1.x 内存管理使用固定槽位的概念。再到hadoop2.0 yarn内存管理的动态container内存管理的概念,再到最后多用户组管理。yarn的资源管理容量算法和公平算法,同样和操作系统的内存管理有着很多相似的地方。

内存管理的无论是操作系统还是JVM,还是集群,都是在沿着相似的方法论在进化。但是,无论如何变化,总是遵从一个原则,方便管理和最在限度利用有限的资源。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值