栈内存用来存储基本类型的变量和对象的引用变量;堆内存用来存储Java中的对象,无论是成员变量,局部变
量,还是类变量,它们指向的对象都存储在堆内存中。
栈内存归属于单个线程,每个线程都会有一个栈内存,其存储的变量只能在其所属线程中可见,即栈内存可以
理解成线程的私有内存;堆内存中的对象对所有线程可见。堆内存中的对象可以被所有线程访问。
如果栈内存没有可用的空间存储方法调用和局部变量,JVM 会抛
出java.lang.StackOverFlowError错误;如果是堆内存没有可用的空间存储生成的对象,JVM 会抛
出java.lang.OutOfMemoryError错误。
栈的内存要远远小于堆内存,如果你使用递归的话,那么你的栈很快就会充满。-Xss选项设置栈内存的大
小,-Xms选项可以设置堆的开始时的大小。
HotSpot 虚拟机将其物理上分为了2个部分 :
> 新生代(young generation)
: 绝大多数最新被创建的对象会被分配到这里
: 对象从这个区域消失的过程我们称之为”minor GC“
-> 新生代三空间
:一个伊甸园空间(Eden )
:两个幸存者空间(Survivor )
创建后待伊甸园 -- 第一次GC --> 其中一个幸存者空间 -- 不断堆积--> 饱和后移动到第二个幸存
者空间 --> 清空饱和空间 --> 几轮后剩下的放入老年代
> 老年代(old generation)
: 对象没有变得不可达,并且从新生代中存活下来,会被拷贝到这
: 对象从老年代中消失的过程,我们称之为”major GC“(或者”full GC“)
> card table
: 存在于老年代 ,512 byte,记录老年代对新生代的应用
: 由一个 write barrier
> 持久代( permanent generation ) 又名 方法区(method area)
: 保存类常量以及字符串常量
> 加快缓存分配
: bump-the-pointer
- 跟踪在伊甸园空间创建的最后一个对象 ,放在顶部,下次创建查找该对象
: TLABs(Thread-Local Allocation Buffers)
- 该方案为每一个线程在伊甸园空间分配一块独享的空间,这样每个线程只访问他们自己的TLAB空间,再
与bump-the-pointer技术结合可以在不加锁的情况下分配内存