堆内内存与对外内存区别

名词解释:

    堆内内存:on-heap memory

    对外内存:off-heap memory


堆内与堆外的关系

     其实堆内堆外是两个相对的关系,堆内内存是我们常用到的。Java分配的非空对象都是由java虚拟机的垃圾收集器管理的,这一部分称为堆内内存,虚拟机会定期对垃圾内存进行回收,在某些特定的时间点,它会进行一次彻底的回收(full gc)。彻底回收时,垃圾收集器会对所有分配的堆内内存进行完整的扫描,这意味着一个重要的事实——这样一次垃圾收集对Java应用造成的影响,跟堆的大小是成正比的。过大的堆会影响Java应用的性能。所以说给应用分配的内存越大,系统性能就越好,因为对应的垃圾回收的代价也就越大,具体如下图:

堆内内存 = 新生代+老年代+持久代

  对于JVM,在jvm参数中只要使用-Xms,-Xmx等参数就可以设置堆的大小和最大值

目前常用的垃圾回收算法有很多种:

     

  • 引用计数器法(Reference Counting)
  • 标记清除法(Mark-Sweep)
  • 复制算法(Coping)
  • 标记压缩法(Mark-Compact)
  • 分代算法(Generational Collecting)
  • 分区算法(Region)
其中 cms是常用的算法。

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

使用堆外内存的优势:
      

1、减少了垃圾回收
因为垃圾回收会暂停其他的工作。

2、加快了复制的速度
堆内在flush到远程时,会先复制到直接内存(非堆内存),然后在发送;而堆外内存相当于省略掉了这个工作。

同样任何一个事物使用起来有优点就会有缺点,堆外内存的缺点就是内存难以控制,使用了堆外内存就间接失去了JVM管理内存的可行性,改由自己来管理,当发生内存溢出时排查起来非常困难。

目前很流行spark技术,经常导致OOM,就是因为堆内内存管理出现问题,但是也提出改进

这一部分后续再添加


部分参考:http://www.jianshu.com/p/50be08b54bee

   spark内存管理机制:https://www.ibm.com/developerworks/cn/analytics/library/ba-cn-apache-spark-memory-management/index.html

猜你喜欢

转载自blog.csdn.net/liuleinevermore/article/details/70141410
今日推荐