java栈
与程序计数器同样,java栈(虚拟机栈)也是线程私有的,其生命周期与线程相同。一般存放基本数据类型,对象引用(一个指向对象起始地址的引用指针或一个表明对象的句柄),reeturnAddress类型(指向一条字节码指令的地址)java
栈区域有两种异常类型:若是线程请求的栈深度大于虚拟机所容许的深度,将抛StrackOverflowError异常;若是虚拟机栈能够动态扩展(大部分虚拟机均可动态扩展),当扩展时没法申请到足够的内存时会抛出OutOfMemoryError异常。hexo
-Xss(StackSpace)栈空间jvm
-Xms ,-Xmx(heap memory space)堆空间:Heap是你们最为熟悉的区域,他是jvm用来存储对象实例的区域,Heap在32位的系统中最大为2G,其大小经过-Xms和-Xmx来控制,-Xms为jvm启动时申请的最小Heap内存,默认为物理内存的1/64,但小于1G,-Xmx为jvm可申请的最大的Heap内存,默认为物理内存的1/4,通常也小于1G,默认当空余堆内存小于40%时,jvm会最大Heap的大小到-Xmx指定大小,可经过-XX:MinHeapFreeRatio来指定这个比例,当空余堆内存大于70%时,JVM会将Heap的大小往-Xms指定的大小调整,可经过-XX:MaxHeapFreeRatio来指定这个比例,但一般为了不频繁调整HeapSize的大小,将-Xms和-Xmx的值设为相同。工具
-XX:PermSize -XX:MaxPermSize:方法区持久代大小:方法区域也是全局共享的,在必定的条件下它也会被 GC,当方法区域须要使用的内存超过其容许的大小时,会抛出 OutOfMemory的错误信息。spa
OutOfMemoryError异常
除了程序计数器外,虚拟机内存的其余几个运行时区域都有发生OutOfMemoryError(OOM)异常的可能,线程
Java Heap 溢出指针
通常的异常信息:java.lang.OutOfMemoryError:Java heap spacess对象
java堆用于存储对象实例,咱们只要不断的建立对象,而且保证GC Roots到对象之间有可达路径来避免垃圾回收机制清除这些对象,就会在对象数量达到最大堆容量限制后产生内存溢出异常。生命周期
出现这种异常,通常手段是先经过内存映像分析工具(如Eclipse Memory Analyzer)对dump出来的堆转存快照进行分析,重点是确认内存中的对象是不是必要的,先分清是由于内存泄漏(Memory Leak)仍是内存溢出(Memory Overflow)。ip
若是是内存泄漏,可进一步经过工具查看泄漏对象到GC Roots的引用链。因而就能找到泄漏对象时经过怎样的路径与GC Roots相关联并致使垃圾收集器没法自动回收。
若是不存在泄漏,那就应该检查虚拟机的参数(-Xmx与-Xms)的设置是否适当。
虚拟机栈和本地方法栈溢出
若是线程请求的栈深度大于虚拟机所容许的最大深度,将抛出StackOverflowError异常。
若是虚拟机在扩展栈时没法申请到足够的内存空间,则抛出OutOfMemoryError异常
这里须要注意当栈的大小越大可分配的线程数就越少。
运行时常量池溢出
异常信息:java.lang.OutOfMemoryError:PermGen space
若是要向运行时常量池中添加内容,最简单的作法就是使用String.intern()这个Native方法。该方法的做用是:若是池中已经包含一个等于此String的字符串,则返回表明池中这个字符串的String对象;不然,将此String对象包含的字符串添加到常量池中,而且返回此String对象的引用。因为常量池分配在方法区内,咱们能够经过-XX:PermSize和-XX:MaxPermSize限制方法区的大小,从而间接限制其中常量池的容量。
方法区溢出
方法区用于存放Class的相关信息,如类名、访问修饰符、常量池、字段描述、方法描述等。
异常信息:java.lang.OutOfMemoryError:PermGen space
方法区溢出也是一种常见的内存溢出异常,一个类若是要被垃圾收集器回收,断定条件是很苛刻的。在常常动态生成大量Class的应用中,要特别注意这点。
《深刻理解java虚拟机》