堆外内存(off-heap),堆内存(on-heap)

香蕉与打火机2015年4月8日java

原文:http://www.infoq.com/cn/news/2014/12/external-memory-heap-memory/

一般情况下,Java中分配的非空对象都是由Java虚拟机的垃圾收集器管理的,也称为堆内内存(on-heap memory)。虚拟机会定期对垃圾内存进行回收,在某些特定的时间点,它会进行一次彻底的回收(full gc)。彻底回收时,垃圾收集器会对所有分配的堆内内存进行完整的扫描,这意味着一个重要的事实——这样一次垃圾收集对Java应用造成的影响,跟堆的大小是成正比的。过大的堆会影响Java应用的性能。

对于这个问题,一种解决方案就是使用堆外内存(off-heap memory)。堆外内存意味着把内存对象分配在Java虚拟机的堆以外的内存,这些内存直接受操作系统管理(而不是虚拟机)。这样做的结果就是能保持一个较小的堆,以减少垃圾收集对应用的影响。

但是Java本身也在不断对堆内内存的实现方式做改进。两者各有什么优缺点?Vanilla Java博客作者Peter Lawrey撰写了一篇文章,在文中他对三种方式:用new来分配对象、对象池(object pool)和堆外内存,进行了详细的分析。

用new来分配对象内存是最基本的一种方式,Lawery提到:

在Java 5.0之前,分配对象的代价很大,以至于大家都使用内存池。但是从5.0开始,对象分配和垃圾回收变得快多了,研发人员发现了性能的提升,纷纷简化他们的代码,不再使用内存池,而直接用new来分配对象。从5.0开始,只有一些分配代价较大的对象,比如线程、套接字和数据库链接,用内存池才会有明显的性能提升。

对于内存池,Lawery认为它主要用于两类对象。第一类是生命周期较短,且结构简单的对象,在内存池中重复利用这些对象能增加CPU缓存的命中率,从而提高性能。第二种情况是加载含有大量重复对象的大片数据,此时使用内存池能减少垃圾回收的时间。对此,Lawery还以StringInterner为例进行了说明。

最后Lawery分析了堆外内存,它和内存池一样,也能缩短垃圾回收时间,但是它适用的对象和内存池完全相反。内存池往往适用于生命期较短的可变对象,而生命期中等或较长的对象,正是堆外内存要解决的。堆外内存有以下特点:

  • 对于大内存有良好的伸缩性
  • 对垃圾回收停顿的改善可以明显感觉到
  • 在进程间可以共享,减少虚拟机间的复制

Lawery还提到对外内存最重要的还不是它能改进性能,而是它的确定性。

当然堆外内存也有它自己的问题,最大的问题就是你的数据结构变得不那么直观,如果数据结构比较复杂,就要对它进行串行化(serialization),而串行化本身也会影响性能。另一个问题是由于你可以使用更大的内存,你可能开始担心虚拟内存(即硬盘)的速度对你的影响了。

Lawery还介绍了OpenHFT公司提供三个开源库:Chronicle Queue、Chronicle Map和Thread Affinity,这些库可以帮助开发人员使用堆外内存来保存数据。采用堆外内存有很多好处,同时也带来挑战,对堆外内存感兴趣的读者可以阅读Lawery的原文来了解更多信息。

堆外内存(off-heap),堆内存(on-heap)相关推荐

  1. gc 堆外_GC解释:堆

    gc 堆外 世代垃圾收集器 JVM堆分为两个不同的世代. 一种称为"年轻",第二种称为"老"(有时称为终身制). 年轻一代又分为两个主要的逻辑部分:伊甸园和幸存 ...

  2. 堆外内存与堆内内存详解

    堆外内存一直是Java业务开发人员难以企及的隐藏领域,究竟他是干什么的,以及如何更好的使用呢?那就请跟着我进入这个世界吧. 一.什么是堆外内存 1.堆内内存(on-heap memory)回顾 堆外内 ...

  3. 深入理解堆外内存 Metaspace

    在之前介绍的分代垃圾回收算法中,我们一直有一个永久代存在,叫 PermGen,内存上它是挨着堆的.为了垃圾回收方便,HotSpot 在永久代上一直是使用老年代的垃圾回收算法. 永久代主要存放以下数据: ...

  4. 如何分析堆外内存使用情况_堆上与堆外的内存使用情况

    如何分析堆外内存使用情况 总览 最近有人问我在Java中使用堆内存的好处和智慧. 面临相同选择的其他人可能会对这些答案感兴趣. 堆外内存没什么特别的. 线程堆栈,应用程序代码,NIO缓冲区都在堆外. ...

  5. 堆上与堆外的内存使用情况

    总览 最近有人问我在Java中使用堆内存的好处和智慧. 面临相同选择的其他人可能会对这些答案感兴趣. 堆外内存没什么特别的. 线程堆栈,应用程序代码,NIO缓冲区都在堆外. 实际上,在C和C ++中, ...

  6. JVM NativeMemoryTracking 分析堆外内存泄露

    为什么80%的码农都做不了架构师?>>>    Native Memory Tracking (NMT) 是Hotspot VM用来分析VM内部内存使用情况的一个功能.我们可以利用j ...

  7. JVM初探——使用堆外内存减少Full GC

    问题: 大部分主流互联网企业线上Server JVM选用了CMS收集器(如Taobao.LinkedIn.Vdian), 虽然CMS可与用户线程并发GC以降低STW时间, 但它也并非十分完美, 尤其是 ...

  8. java堆外内存6_Java堆外内存排查小结

    简介 JVM堆外内存难排查但经常会出现问题,这可能是目前最全的JVM堆外内存排查思路.之前的文章排版太乱,现在整理重发一下,内容是一样的. 通过本文,你应该了解: pmap 命令 gdb 命令 per ...

  9. Java堆外内存:堆外内存溢出问题排查

    一.堆外内存组成 通常JVM的参数我们会配置 -Xms 堆初始内存  -Xmx 堆最大内存  -XX:+UseG1GC/CMS 垃圾回收器  -XX:+DisableExplicitGC 禁止显示GC ...

  10. java 监控 native 内存_JVM NativeMemoryTracking 分析堆外内存泄露

    Native Memory Tracking (NMT) 是Hotspot VM用来分析VM内部内存使用情况的一个功能.我们可以利用jcmd(jdk自带)这个工具来访问NMT的数据. NMT介绍 工欲 ...

最新文章

  1. Cocos creator加载场景、加载场景回调、预加载场景
  2. SAP零售行业解决方案初阶 1
  3. js调用linux命令,xshell调用js脚本开发
  4. lamda list 分组_java8lambda表达式对集合分组并且排序(记一次性能优化案例)
  5. Faster RCNN 训练自己的检测模型
  6. 穷不过三代,囧不过三个公司——程序员如何通过努力让自己看上去很光鲜
  7. 什么叫显示动力学_什么叫显示动力学,什么叫隐式动力学分析!
  8. BZOJ 3876 支线剧情
  9. Spring-ConfigurationClassPostProcessor类
  10. python有道云笔记_你很需要的,一个一键导出「有道云笔记」所有笔记的功能
  11. CenterNet-Objects as Points论文翻译
  12. 英语听力采用计算机化考试,今年的北京普通高考英语听力有何不同?
  13. SAA7113视频解码芯片介绍
  14. jquery查找指定id元素下的某个或某些元素
  15. Python-xlsx转置,行转列,列转行
  16. 金额大小写转换,这里有两种方法提供给你
  17. Frida 代码提示
  18. 如何利用SEO方式使网站增加流量
  19. 你是从哪个细节发现女朋友出轨的?
  20. 电机远计算机控制,电机控制器

热门文章

  1. 「LCA」[USACO10HOL]牛的政治Cow Politics
  2. Mob平台获取手机验证码
  3. 电脑可以上网,但是仍然显示无网络连接
  4. 东数西算,浪潮云在枢纽节点提供服务
  5. InstallShield脚本使用笔记
  6. 2022年HGAME中REVERSE的Flag Checker
  7. python将xls转换为xlsx_python – 如何将xls转换为xlsx
  8. 三城记:中国创客地图
  9. android10 psp模拟器,PPSSPP(PSP模拟器) V1.10 安卓版
  10. PHP数字球,球体的计算