1 堆内存和非堆内存
JVM内存划分为堆内存和非堆内存,堆内存分为年老代(Young Generation)、老年代(Old Generation),非堆内存就一个永恒代(Permanent Generation)。

年老代又分为Eden和Survivor区。Survivor区由FromSpace和ToSpace组成。Eden区占大容量,Survivor两个区占小容量,默认比例是8:1:1。

官网举荐新生代占堆的的3/8,Survivor占新生代的1/10。

堆内存用处:寄存的是对象,垃圾收集器就是收集这些对象,而后依据GC算法回收。

非堆内存用处:永恒代,也称为办法区,存储程序运行时长期存活的对象,比方类的元数据、办法、常量、属性等。

在JDK1.8版本废除了永恒代,代替的是元空间(MetaSpace),元空间与永恒代上相似,都是办法区的实现,他们最大区别是:永恒代应用的是JVM的堆内存空间,而元空间应用的是物理内存,间接受到本机的物理内存限度。在前面的实际中,因为笔者应用的是JDK8,所以打印出的GC日志外面就有MetaSpace。

2 JVM堆外部构型(新生代和老年代)
Jdk8中曾经去掉永恒区,这里为了与时俱进,不再赘余。

上图演示Java堆内存空间,分为新生代和老年代,别离占Java堆1/3和2/3的空间,新生代中又分为Eden区、Survivor0区、Survivor1区,别离占新生代8/10、1/10、1/10空间。

问题1:什么是Java堆?

答复1:JVM标准中说到:”所有的对象实例以及数组都要在堆上调配”。Java堆是垃圾回收器治理的次要区域,百分之九十九的垃圾回收产生在Java堆,另外百分之一产生在办法区,因而又称之为”GC堆”。依据JVM标准规定的内容,Java堆能够处于物理上不间断的内存空间中,然而逻辑上要求是间断的。

问题2:为什么Java堆要分为新生代和老年代?

答复2:以后JVM对于堆的垃圾回收,采纳分代收集的策略。依据堆中对象的存活周期将堆内存分为新生代和老年代。在新生代中,每次垃圾回收都有少量对象死去,只有大量存活。而老年代中寄存的对象存活率高。这样划分的目标是为了使 JVM 可能更好的治理堆内存中的对象,包含内存的调配以及回收。java培训

问题3:为什么新生代要分为Eden区、Survivor0区、Survivor1区?

答复3:这是构造与策略相适应的准则,新生代垃圾收集应用的是复制算法(一种垃圾收集算法,Serial收集器、ParNew收集器、Parallel scavenge收集器都是用这种算法),复制算法能够很好的解决垃圾收集的内存碎片问题,然而有一个人造的缺点,就是要就义一半的内存(即任意时刻只有一半内存用于工作),这对于贵重的内存资源来说是极度侈靡的。新生代在应用复制算法作为其垃圾收集算法的时候,对其做了优化,拿出2/10的新生代的内存作为替换区,称为Survivor0区和Survivor1区(留神:有的博客上称为From Survivor Space和To Survivor Space,这样论述也是对的,然而容易对初学者造成误导,因为在复制算法中,复制是双向的,没有固定的From和To,这一次是由这一边到另一边,下次就是从另一边到这一边,应用From Survivor Space和To Survivor Space容易让起初学习者误以为复制只能从一边到另一边,当然有的博客中会附加不论从哪边到哪边,起始就是From,起点就是To,即From Survivor Space和To Survivor Space所对应的区循环对调,然而读者不肯定想的明确。所以笔者这里应用Survivor0、Survivor1,缩小误会)

所以说,新生代在结构上分为Eden区、Survivor0区、Survivor1区,是与其应用的垃圾收集算法(复制算法)相适应的后果。

问题4:对于永恒区Permanent Space?

答复4:因为Jdk8中勾销了永恒区Permanent Space,本文为与时俱进,不再讲述Permanent Space。