JVM使用的内存分为两部分:堆(Heap)和栈(Stack),简单理解,堆可以看做是数据区,栈可以看做是指令区;下面详细说明二者的区别。
堆中存放的是对象实例(但不包括对象的方法,因为方法是指令,放在栈里),new出来的对象都放在堆里,对象不再被使用(不可达)时由GC(垃圾回收)机制回收,而无需代码显式释放,堆由于是在运行时动态分配的,因此存取速度比较慢;
栈中存放基本数据类型(primitive types: byte, int, float, long, char, boolean, etc)、常量、指令(例如对象的方法)和对象的引用地址(对象实例在堆中分配以后,需要在栈中保存一个4字节的堆内存地址,也就是所谓的对象句柄,用来确定该对象实例在堆中的位置)。栈中数据存取的速度比堆快,仅次于寄存器,但它必须在编译期间指定,且由于它采用FIFO(first in, first out)方式分配内存,因此不存在内存回收问题,因此GC是仅工作在堆上的。
堆又可以分为3个部分:年轻代(Young Generation,YG)、老代(Old Generation,OG)和永久代(Permanent Generation,PG),新创建的对象都放在YG里,经过几次GC后仍然生存的就被放到了OG里,PG里放的是类信息以及相关元数据(详见[1]);YG的GC最频繁,PG的GC最少,这样可以极大地提高JVM的性能;
[1] 维基百科对JVM的堆的说明:http://en.wikipedia.org/wiki/Java_Virtual_Machine#Heap