JAVA内存区域与内存溢出异常
一 Java内存区域
Java虚拟机在执行java程序的过程中会把它管理的内存划分为若干个不同的数据区域,Java虚拟机所管理的内存包含以下几个运行时数据区域。
1.程序计数器
程序计数器是一块比较小的内存空间,它可以看做是当前线程所执行的字节码的行号指示器。字节码解释器工作就是通过改变计数器的值来选取下一条执行的指令,分支、循环、异常处理,线程恢复等基础功能都需要依赖计数器去完成。
Java虚拟机的多线程是通过线程轮流切换并分配处理器执行时间的方式来实现,每条线程都有一个独立的程序计算器,各个线程之间计数器互不影响,独立存储
2.Java虚拟机栈
a.虚拟机栈是线程私有的 b.声明周期与线程一样 c.局部变量表中可以存放各种基础数据类型,对象引用 ,其中 64位长度的long和double类型的数据占两个局部变量空间,其他的占一个,局部变量所需的内存空间在编译期间完成分配。 d.如果线程请求的栈深度大于虚拟机允许的深度,抛出StackOverflowError;如果虚拟机可以动态扩展,扩展时没法申请到足够的内存,抛出OutOfMemoryError.
3.本地方法栈
与虚拟机栈的作用很相似,不过本地方法栈是为Native方法服务,虚拟机栈为执行java方法服务
4.Java堆
a.被所有线程共享 b.在虚拟机启动时创建 c.存放对象实例 d.堆中没有存在完成实例分配,并且堆也无法再扩展,抛出OutOfMemoryEoor
5.方法区
a.被所有线程共享 b.存放编译器编译后的数据,类信息,常量,静态变量 c.可以不实现垃圾收集 d.当方法区无法满足内存分配时抛出OutOfMemoryError
6.常量池
常量池是方法区的一部分,Class文件中除了有类的版本,字段,方法,接口等信息外,还有常量池,用于存在基本类型和对象类型、以文本形式的符号引用。比如:类和接口的全限定名;字段和方法的名称与描述符;,编译时,如果发现对其它类方法的调用或者对其它类字段的引用的话,记录进class文件中的只能是一个文本形式的符号引用,在连接过程中,虚拟机根据这个文本信息去查找对应的方法或字段