JAVA虚拟机的基本机构 JVM堆空间布局 首先为什么分代: 1.不同类型对象的生命周期是不一样的; 2.不同年代的对象采取不同的收集方式,以便提高回收效率; 3.如果不分代,每次垃圾回收都需要遍历内存空间,花费时间较长,效率低; 4.如果不分代,多次垃圾回收后,生命周期长的对象仍然存在,效率低; 年轻代: 1.新生成的对象首先都是分配在年轻代的; 2.年轻代的目标就是尽可能快速的收集掉那些生命周期短的对象; 年轻代的结构: 1.Eden:Eden用来存放JVM刚分配的对象; 2.Survivor1 和Survivro2:两个Survivor空间一样大,当Eden中的对象经过垃圾回收没 有被回收掉时,会在两个Survivor之间来回 Copy,当满足某个条件,比如Copy次 数,就会被Copy到Tenured; 年轻代内存的设置: 1.SurvivorRatio=eden/from=eden/to 伊甸园 空间和幸存者空间的 比值; 2.NewRatio=tenured/young 老年代内存和年轻代内存比值; 设置策略: 1.尽可能将对象预留在新生代; 2.减少老年代GC 次数; 老年代: 1.在年轻代中经历了N次垃圾回收后仍然存活的对象,就会被放到老年代; 2.老年代中存放的都是一些生命周期较长的对象,例如: Session对象、Socket连 接等; MaxTenuringThreshold: 1.MaxTenuringThreshold是年轻代和老年代的临界值; 2.MaxTenuringThreshold用于控制对象能经历多少次Minor GC才晋升到老年代; 3.每发生一次Minor GC,年龄就增加1岁,当它的年龄增加到临界值(默认为15 岁),就将会被晋升到老年代中 ; 永久代(持久代)内存: 1.永久代内存用于保存类信息。方法区的大小决定了系统可以保存多少个类; 2.如果定义了太多的类,会导致永久代内存溢出; 3.在JDK1.8中,废弃永久代,取而代之的是元数据区( Metaspace ) ; 直接内存: 1.直接内存常用于使用NIO的场景,例如:mina,netty框架;参考 DirectBufferOOM、 ByteBuffer ; 2.直接内存跳过了java堆,使java程序可以直接访问原生内存空间,因此,直接内存访 问速度会快于堆内存; 3.直接内存适合申请次数较少,访问较频繁的场合。如果内存空间本身需要平衡申请, 则不适合使用直接内存;