为什么80%的码农都做不了架构师?>>>
JAVA内存划分
JAVA虚拟机在运行程序的时候会将内存划分成几个区域,这些区域有各自的用途,包括以下几个区域
程序计数器、虚拟机栈、堆、方法区(包含常量池)
其中和线程保持一致的有程序计数器,虚拟机栈,数据共享的区域是堆和方法区
1、程序计数器是记录线程指令执行的相关步骤的计数器,每个线程各自拥有一个程序计数器,程序计数器的长度是固定的,也是这几个内存划分中不会有OMM和SOE异常的内存区域
2、虚拟机栈(此处包含本地方法栈)可以在模糊意义上和我们平常所说的栈相互关联起来,这个区域的生命过程和线程是保持一致的,这个虚拟机栈描述的是JAVA方法执行的内存模型,每个方法执行都会保存局部变量表、操作数栈。。。。(一般我们关注的是局部变量表),需要知道的是局部变量表中包含的是基本数据类型以及引用类型,此处的引用可以是直接指向一个对象的指针引用,也可是一个句柄(中间量,句柄中存放相关对象的指针),需要注意的是方法中的局部变量在编译的期间已经确定了相关的大小,
Q:既然是编译期间就计算好了相关的大小,那么为什么还有stackOverflowError和OMM异常呢?
A:由于线程执行的时候并不是一个方法执行到底的,方法中会调用其他的方法,而在方法不退出的时候局部变量还是保存在栈中的,如果是相关的递归的调用,方法栈比较深,这样需要保存局部变量的内存就会变得大了起来,就会产生相关的异常
3、堆 堆一般来说应该是JVM中内存最大的一块区域,这个区域保存着所有的实例信息,且被所有的线程所共享的一块内存区域,这个区域也是GC回收的重点区域
4、方法区 这个区域保存着类的相关信息、常量池、静态变量,也是所有线程所共享的一块区域
OMM异常信息(OutOfMemoryError)
除了程序计数器的内存区域不会产生OMM异常外,所有其他的内存划分区域都会产生OMM异常
1、栈空间产生OMM异常,栈空间的OMM异常和StacKOverFlowError异常本质上都是内存不够用的异常,一般的产生原因是无限制的递归
2、堆空间的OMM异常,一般是多线程下的对象创建比较多,且不释放相关对象的引用,导致GC无法回收,产生OMM
3、方法区的异常 相关的动态字节码生成技术,产生大量的class信息,导致内存不够产生异常,当然在1.7之前的版本中,String的intern的本地方法第一次产生的字符串常量在堆上面创建对象之后,会拷贝相关的信息到常量池中,所以String的intern方法返回的是常量池中的引用。如果产生足够多的常量也会产生OMM异常
转载于:https://my.oschina.net/guanhe/blog/1576273
最后
以上就是大胆绿草最近收集整理的关于JAVA内存区域及内存溢出异常——总结的全部内容,更多相关JAVA内存区域及内存溢出异常——总结内容请搜索靠谱客的其他文章。
发表评论 取消回复