1.堆内存的组成结构
* jdk1.8之前

新生代:那些刚刚创建的对象,刚刚创建的对象有可能有很多垃圾对象,那么这些对象是优先被回收的;
老年代:老不死的对象,经过很多次的清理之后,该对象依然有用;
永久代:intern()方法进行入池的对象其实就在永久代中,永久代不会被回收,除非jvm崩溃了。(jdk1.8之后将其更换为元空间,元空间是电脑的直接内存。)
伸缩区:在整个内存的组成过程之中每一代的内存空间中都有个伸缩区,那么该区域就可以有Jvm根据空间的使用情况动态扩充;当我们合理的设置了伸缩区的内存之后,那么就可以得到良好的性能提升,也就是说最容易做的性能提升就是改变伸缩区的内存占用大小。
* jdk1.8

2.对象的创建与垃圾回收
在Java之中有gc的概念,那么有两种调用方式:自动调用、手工调用(Runtime.getRuntime.gc())。gc的手动调用前提是我们知道哪里有垃圾,所以常用的会是进行自动的调用,那么自动的调用什么时候会执行?这里涉及到两类的gc操作(Minor GC、Full GC):
对象的创建:

1) 当现在的程序之中需要产生新的实例化对象(关键字new、对象克隆、反射实例化)的时候,就需要新的内存空间的开辟,所以此时就要进行内存空间的申请;
2) 新对象要申请的对象空间默认都在伊甸园区(新生)进行开辟,所以首先要判断伊甸园区是否用空余的内存空间,如果有空余的内存空间,则直接在伊甸园区开辟新的堆内存空间,此时不会发生GC处理;
3) 如果新对象的申请无法在伊甸园空间申请出新的空间,那么就表现出伊甸园区的内存空间不足,不足就需要将那些无用的新对象进行回收(Minor GC),当我们回收完成之后要继续判断该空间是否可以容纳下新的对象,如果可以容纳,则开辟新的内存空间保存新对象;
4) 如果此时伊甸园区及时执行了Minor GC操作之后发现依然没有可以被回收的新对象,那么这个时候将继续判断存活区是否有空间(存活区一般与伊甸园区的比率是1:1:8即(FormSpace:ToSpace:Eden = 1:1:8)),如果存活去有空余空间,则将那些在伊甸园区依然活跃的部分对象直接保存到存活区,就相当于伊甸园区可以腾出部分的空间(这个空间非常的小)来,供我们的新对象进行使用;
5) 如果此时存活区依然满了(空间不足),那么继续向老年代进行空间的申请,首先判断老年代的空间是否有空余,如果有空余就将存活区的活跃对象保存到老年代,而后存活区得到空间释放,伊甸园区也就得到了空间释放,则新对象空间申请成功;
6) 如果现在老年代也是满的,那么这个时候会执行Full GC(完全GC/Major GC)进行老年代的内存释放,如果可以释放成功,则进行新对象的保存,如果释放不成功则表示已经没有无用的内存空间了,那么就会抛出OOM(Out Memory Error)错误。




