Java堆内内存和堆外内存

1、堆内内存概念

堆内一般指堆内内存,英文全称:on-heap memory (heap:堆,java的内存区)

java虚拟机分配非空对象一般就放到堆内内存,并且虚拟机会定期会进行垃圾回收在某些特定的时间点,它会进行一次彻底的回收(full gc)。full gc时,垃圾收集器会对所有分配的堆内内存进行完整的扫描,这样一次垃圾收集对Java应用造成的影响,跟堆的大小是成正比的。所以通过堆外内存来解决该问题

2、堆内内存认知

堆内内存 = 新生代+老年代+持久代
对于JVM,在jvm参数中可使用-Xms,-Xmx等参数就可以设置堆的大小和最大值
Java堆内内存和堆外内存_第1张图片

  • 年轻代 (Young Generation)-即新生代

(1)存放的是新生成的对象

(2)年轻代的目标是尽可能快速的收集掉那些生命周期短的对象

(3)Eden 大部分对象在Eden区中生成

当Eden区满时, 依然存活的对象将被复制到Survivor区, 当一个Survivor 区满时, 此区的存活对象将被复制到另外一个Survivor区,Survivor通常2个

  • 老年代 (Old Generation)

(1)存放了在年轻代中经历了N次垃圾回收后仍存活的对象, 是一些生命周期较长的对象

  • 持久代 (Permanent Generation)

(1)存放静态文件, 如静态类和方法等。持久代对垃圾回收没有显著影响, 但是有些应用可能动态生成或者调用一些class, 比如Hibernate, Mybatis 等, 此时需要设置一个较大的持久代空间来存放这些运行过程中新增的类。

(2)设置持久代大小参数: -XX:MaxPermSize= Perm => Permanent

3、堆外内存

堆外一般指堆外内存,英文全称:off-heap memory

堆外内存指的是java虚拟机堆以外的内存,这个区域是受操作系统管理,而不是jvm。

4、堆外内存的优点和缺点

  • 使用堆外内存的优点
    (1)减少了垃圾回收机制(FULL GC 会暂停其他的工作)对应用程序造成的影响
    (2)加快了复制的速度:堆内在flush到远程时, 会先复制到直接内存(非堆内存), 然后再发送。而堆外内存(本身就是物理机内存)几乎省略了该步骤
  • 使用堆外内存的缺点
    (2)内存难以控制
    使用了堆外内存就间接失去了JVM管理内存的可行性,改由自己来管理,当发生内存溢出时排查起来非常困难。

5、垃圾回收(GC)

  • Scavenge GC
    (1)一般当新对象生成并且在Eden申请空间失败时就会触发Scavenger GC, 对Eden区域进行GC, 清除非存活对象, 并且把尚存活的对象移动到Survivor区, 然后整理两个Survivor区。
    (2)该方式的GC是对年轻代的Eden区进行,不会影响到年老代。
    (3)由于大部分对象是从Eden区开始的, 同时Eden区分配的内存不会很大, 所以Eden区的GC会很频繁。
  • Full GC
    (1)对整个堆进行整理, 包括Young, Tenured 和Permanent。
    (2)所消耗的时间较长, 所以要尽量减少 Full GC 的次数

导致 Full GC 的可能原因:

(1)老年代(Tenured) 被写满
(2)持久代(Permanent) 被写满
(3)System.gc() 被显示调用
(4)上一次GC之后Heap 的各域分配策略动态变化

你可能感兴趣的:(Java,java,开发语言,后端)