Java深刻 - Java内存区域详解

Java和c c++不同,c c++都是直接经过手动的方式来申请内存,释放内容。而java拥有良好的内存自动管理机制。因此在咱们开发java程序代码的时候,通常状况下不须要关心java的内存问题。java

Java的内存区域图:c++

上面的图就是Java运行时的内存数据区域。分红方法区,虚拟机栈,本地方法栈,堆,程序计数器。数组

 

程序计数器

做用:程序计数器是一块很小的内存空间,主要是线程所执行的字节码的行号指示器。每一个线程都会有独立的程序计数器。工具

 

虚拟机栈

Java的虚拟机栈也是线程私有的,生命周期和线程相同。虚拟机栈描述的是Java方法执行的内存模型:每一个方法被执行的时候都会同时建立一个栈帧(Stack Frame)用于存储局部变量表、操做数栈、动态连接、方法出口等信息。每一个方法被调用直至执行完成的过程,就是对应着一个栈帧在VM Stack中从入栈到出栈的过程。spa

本地方法栈主要为虚拟机使用的Native方法服务,也是栈的一部分。线程

虚拟机栈会抛两种异常:code

1. StackOverflowError异常。一般主要是线程请求的栈深度大于虚拟机所容许的深度。好比递归层次太深就有可能致使这个异常出现,通常1000-2000层之间。减小递归层次能够减少这个防范。也能够经过参数-Xss128k 能够设置每一个线程的栈大小。对象

2. OutOfMemoryError异常。主要是内存不够。递归

 

Java堆

Java内存中最大的块就是堆。全部的对象实例和数组都会分配在java的堆上面。Java堆也是内存GC的重要区域。生命周期

Java堆异常:

1. OutOfMemoryError异常。Java堆内存溢出能够经过设置参数-Xmx3550m -Xms3550m来控制堆内存的大小。-Xms是最小值,-Xmx是最大值。

通常堆溢出:java.lang.OutOfMemoryError: Java heap space

异常提示中都有Java heap space 说明是堆溢出。

通常解决堆溢出思路有三种:

1. 经过内存影像分析工具(Eclipse Memory Analyzer)来定位堆溢出问题

2. 分析是否有内存泄露

3. 调整堆参数。

 

方法区

方法区也是各线程共享的内存区域,主要存放虚拟机加载的类信息、常量、静态变量等信息。

运行时常量池也是方法区的一部分,做用是存储编译期生成的各类字面量和符号引用。

1. OutOfMemoryError异常。发生异常时,主要抛下面相似的异常信息:

 

Exception in thread "main" java.lang.OutOfMemoryError: PermGen space  
    at java.lang.String.intern(Native Method)  
    at org.fenixsoft.oom.RuntimeConstantPoolOOM.main(RuntimeConstantPoolOOM.java:18)


能够看到有 PermGen space的提示则表示方法区溢出。

 

方法区溢出,能够经过限制方法区的内存大小来限制:-XX:PermSize 和 -XX:MaxPermSize

Java1.7的PermGen默认空间为85 MB(或者能够经过-XX:MaxPermSize=XXXm指定)

须要注意的是,PermGen space是Oracle-Sun Hotspot才有,JRockit以及J9是没有这个区域。

相关文章
相关标签/搜索