java 内存移到堆外!!! Jvm gcih 淘宝优化JVM实践

官方地址

Jvm gcih

出自Jvm  GC-Invisible Heap

什么是GCIH

GC-Invisible Heap,简称GCIH,是一种将Java对象从Java堆内移动到堆外,并且可以在JVM间共享这些对象的技术。

为什么要用GCIH

 GCIH顾名思义就是GC访问不到的堆,它是对JVM内存管理机制的一个有益的补充。
 在某些特殊的应用中有大量生命周期很长的对象,在应用运行的整个过程中它们都存在,不需要被GC回收。如果这类对象很多,总体占用内存比例高,那么他们的存在将给GC带来很多不必要的工作负担。例如在淘宝的很多应用中都具有大量的Forest对象,目前这些对象已经占用超过400MB,它们本身在应用提供服务前创建,在服务过程中永远存在。那么实际在GC的收集工作中针对这些对象的所有访问、操作其实都是“无用功”。如果我们把这些对象 从Java堆内移动到堆外,那么这些对象所占用的Java堆内空间将被释放,GC的工作量将会降低,从而每次full GC的时间将会缩短。
 除此以外,目前JVM间没有很高效的内存/对象共享技术,GCIH为在JVM间共享内存/对象提供了必要的基础。通过这种技术可以将那些移动到GCIH内对象在JVM间共享,从而减少内存的总体占用。

GCIH + Hesper + Forest线上测试结果对比

下面的性能测试数据来自于线上gcih + hesper + forest的实际压测数据,具体结论由淘宝性能测试团队统计。

  • 系统load对比
 在相同的tps下,采用gcih的hesper响应时间明显要比不采用gcih的hesper的响应时间要低。随着压力的不断增加,tps超过55后,非gcih的hesper响应时间明显上升速度加快,当tps上升至72后,响应时间直接飙至200ms以上。而采用gcih的响应时间上升速度则相对于平缓。
  • 机器资源消耗对比
 在tps处于20~50之间时,gcih的load要略低于非gcih。在tps超过55后,非gcih的load出现急速上升。 在tps相同的情况下,gcih的cpu消耗约降低20%~30%.
  • 单机最大能力对比
 当load达到5~6之间、且RT<200ms的情况下,hesper(非gcih)的tps约为46~55左右,hesper(gcih)的tps值约为60~68左右。此时,hesper(非gcih)的单机能力比hesper(gcih)提升20%;
 当load<15,cpu使用率<85%的情况下,hesper(非gcih)的最大单机能力为tps:68~70,hesper(gcih)的tps值约为88左右。此时计算,采用gcih的hesper应用单机最大能力可提升25%。
  • 综上:gcih的性能明显优于非gcih,可以使单机能力提升20%左右。

GCIH内存共享

有关GCIH内存共享

GCIH 内存共享有以下特点:

  • 不经过JNI调用
  • 没有序列化和反序列化
  • GC性能提高
  • 数据更集中,cache命中率提高

GCIH内存共享与Hadoop

  • Map/Reduce 有时需要一些公用的对象,每个client JVM都有一份拷贝。
  • 一旦初始化好,在使用过程中是只读的
  • 对象比较大,占用较多内存,甚至成为瓶颈
  • 一个实际场景,dump中心的UDP,用来做join的一些公共Hashmap共享后可以节约内存,甚至可能提高效率(如果内存是瓶颈)

下图显示了使用GCIH内存共享功能后的Hadoop系统状况,左边的图表示使用GCIH前系统内每个JVM进程内均有一份对象的拷贝, 右边的图显示使用GCIH后多个JVM进程共享一份数据,有效降低了物理内存的使用。

官方地址

官方地址

官方地址

java 内存移到堆外!!! Jvm gcih 淘宝优化JVM实践,码迷,mamicode.com

时间: 2024-10-01 02:49:28

java 内存移到堆外!!! Jvm gcih 淘宝优化JVM实践的相关文章

Java内存分配之堆、栈和常量池(转)

摘录自http://www.cnblogs.com/SaraMoring/p/5687466.html Java内存分配主要包括以下几个区域: 1. 寄存器:我们在程序中无法控制 2. 栈:存放基本类型的数据和对象的引用,但对象本身不存放在栈中,而是存放在堆中 3. 堆:存放用new产生的数据 4. 静态域:存放在对象中用static定义的静态成员 5. 常量池:存放常量 6. 非RAM(随机存取存储器)存储:硬盘等永久存储空间 *********************************

JAVA内存管理之堆内存和栈内存

我们常常做的是将Java内存区域简单的划分为两种:堆内存和栈内存.这种划分比较粗粒度,这种划分是着眼于我们最关注的.与对象内存分配密切相关的两类内存域.其中栈内存指的是虚拟机栈,堆内存指的是java堆. 1.栈内存,即虚拟机栈.每个方法被执行的时候都会同时创建一个栈帧,用来存储局部变量,操作栈,动态链接,方法出口等信息.局部变量包括各种基本类型的变量和对象的引用变量都是在方法的栈内存中分配.其中,64位长度的long和double类型的数据占用2个局部变量的空间,其他数据类型只占用1个.局部变量

java内存分配(堆、栈、常量池)

Java内存分配: ◆寄存器:我们在程序中无法控制 ◆栈:存放基本类型的数据和对象的引用,以及成员方法中的局部变量 ◆堆:存放对象本身(成员变量+成员方法的引用) ◆静态域:存放在对象中用static定义的静态成员 ◆常量池:存放常量 ◆非RAM存储:硬盘等永久存储空间 栈的存取速度比堆快,仅次于寄存器. 常量池:专门用于存储.管理在编译时就可以确定的保存在.class文件中的一些数据.包括代码中所定义的各种基本类型(如int.long等等)和对象型(如String及数组)的常量值(final)

外媒探访“淘宝村”:阿里改变偏远地区命运

英国<卫报>旗下<卫报周刊>( Guardian Weekly)近日刊登了一篇题为"阿里巴巴(滚动资讯)使数字经济的益处传到中国最偏远地区"的文章,<卫报周刊>记者Harold Thibault走访了福建省"淘宝第一村"培斜村,见证了电子商务如何改变了这个偏远农村地区的面貌. 培斜村是网络电商巨头阿里巴巴所选的20个淘宝村之一,在大多数中国农村地区,年轻人都去了繁华的大城市,但在培斜村却正好相反. 第一眼望去,这个偏远乡村好像和2

JVM - 堆外内存

看了不少资料,总结下: 堆外内存 / 直接内存(Direct Memory)JDK1.4中引入的NIO类,基于channel和Buffer的I/O方式,可用Native库直接分配堆外内存,然后利用一个存储在堆中的DirectByteBuffer对象作为这块内存引用来操作.避免了在Java堆和Native堆中来回复制数据. 优点 1.堆外内存不影响 JVM GC,程序会减少 Full GC. 2 IO 操作使用堆外内存比堆内存快.因为堆内在flush到远程时,会先复制到直接内存(非堆内存),然后在

JVM源码分析之堆外内存完全解读

概述 广义的堆外内存 说到堆外内存,那大家肯定想到堆内内存,这也是我们大家接触最多的,我们在jvm参数里通常设置-Xmx来指定我们的堆的最大值,不过这还不是我们理解的Java堆,-Xmx的值是新生代和老生代的和的最大值,我们在jvm参数里通常还会加一个参数-XX:MaxPermSize来指定持久代的最大值,那么我们认识的Java堆的最大值其实是-Xmx和-XX:MaxPermSize的总和,在分代算法下,新生代,老生代和持久代是连续的虚拟地址,因为它们是一起分配的,那么剩下的都可以认为是堆外内存

Java 堆外内存

入口ByteBuffer.allocateDirect public static ByteBuffer allocateDirect(int capacity) { return new DirectByteBuffer(capacity); } DirectByteBuffer构造函数 DirectByteBuffer(int cap) { // package-private super(-1, 0, cap, cap); boolean pa = VM.isDirectMemoryPag

从0到1起步-跟我进入堆外内存的奇妙世界

堆外内存一直是Java业务开发人员难以企及的隐藏领域,究竟他是干什么的,以及如何更好的使用呢?那就请跟着我进入这个世界吧. 一.什么是堆外内存 1.堆内内存(on-heap memory)回顾 堆外内存和堆内内存是相对的二个概念,其中堆内内存是我们平常工作中接触比较多的,我们在jvm参数中只要使用-Xms,-Xmx等参数就可以设置堆的大小和最大值,理解jvm的堆还需要知道下面这个公式: 堆内内存 = 新生代+老年代+持久代 如下面的图所示: 在使用堆内内存(on-heap memory)的时候,

Java虚拟机的内存组成以及堆内存介绍

一.java内存组成介绍:堆(Heap)和非堆(Non-heap)内存 按照官方的说法:“Java 虚拟机具有一个堆,堆是运行时数据区域,所有类实例和数组的内存均从此处分配.堆是在 Java 虚拟机启动时创建的.”“在JVM中堆之外的内存称为非堆内存(Non-heap memory)”.可以看出JVM主要管理两种类型的内存:堆和非堆.简单来说堆就是Java代码可及的内存,是留给开发人员使用的:非堆就是JVM留给 自己用的,所以方法区.JVM内部处理或优化所需的内存(如JIT编译后的代码缓存).每