JAVA之所以被称为“平台无关的编程语言”就是因为JAVA虚拟机的存在。
那么什么是JAVA虚拟机呢?
JAVA虚拟机即是运行在操作系统中的一个进程,它能够加载开发人员编写的class文件,由JVM中的类加载器来进行加载。
JVM的内存结构
主要分为线程共享内存区和线程私有内存区。
线程共享区中包含:JAVA堆,方法区;
线程私有区中包含:JAVA栈,本地方法栈,程序计数器(PC寄存器);
可如图表示:
堆区中还分为:新生代,年老代,永久代;
新生代还分为:Eden区,From Survivor,To Survivor;
为什么要对堆区进行分代呢?
其实分代并不是必须的,分代也是为了对GC的性能进行优化。首先从内存空间上来讲,堆区占用的内存是最大的,存放着大量的对象,同时也是垃圾回收时,重点回收的一个区域。当需要进行GC时,如果所有的对象都放在了一块,GC就需要对整个堆区进行扫描,找出无用的对象,这将会大大的浪费系统资源,且效率低下。而在JAVA中大多数的对象存活时间都不会太长,如果进行分代,把新创建的对象都放在一个区域内,当GC时,先对这个区域进行回收,将有可能会清理出很大的空间。
新生代
JVM把新生代分为三个区域:Eden区,To Survivor区,FromSurvivor区;
一般新建的对象都会放到新生代的Eden区,这个区域也是垃圾回收最频繁的区域。当这些对象经过一次MinorGC后,存活下来的对象会被移动到To Survivor区中。当To Survivor区的内存空间不足时,会把还存活的对象移动到From Survivor区。当From Survivor区中的对象经过15次MinorGC以后还存活下来的话,将会被移动到年老代。新生代采用的垃圾回收算法是复制整理算法。
年老代
当对象在年轻代的From Survivor区中经历了15次MinorGC后,就会被移动到年老代。当年老代的空间不足时,会进行MajorGC。年老代采用的垃圾回收算法是标记-清除算法。