【夹娃系列】java面试基础知识储备(¥2)——JVM内存划分和内存溢出异常的原因和解决方法

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Handoking/article/details/84179469

JVM内存划分和内存溢出

JVM内存划分

在这里插入图片描述
堆:存放对象实例,被所有的线程共享的一块区域。垃圾收集器管理的主要区域。
方法区:存储虚拟机加载的类信息,常量,静态变量,编译后的代码等数据。有时被成为永久代(HotSpot虚拟机上这么称谓)
虚拟机栈:每一个方法在运行时都会产创建一个栈帧,用来存储局部变量表,操作数栈,动态链接,方法出口等信息。局部变量表中存放了编译期就知道的各种基本数据类型,对象的引用等。常见的错误为:StackOverflowError
本地方法栈:为虚拟机使用到的本地方法服务。很多虚拟机中将虚拟机栈和本地方法栈合二为一。其作用和虚拟机栈是一样的。
程序计数器:占用比较小 的空间。类似于一般操作系统中的pc计数器,通过改变计数器的值,来执行下一条字节码的指令。相当于字节码的行号指示器,进行分支跳转或者循环,异常处理等操作。

内存溢出的异常和解决办法

1.Java.lang.OutOfMemoryError: PermGen space
错误:永久代区域发生了内存溢出,发生在方法区!
原因:一是方法区中运行时常量池溢出,就是在运行过程中产生了大量的常量比如i++无限循环的产生。二是调用的类太多,导致方法区内存溢出。
解决:手动设置MaxPermSize大小(在编译器中可以设置)

2.java.lang.OutOfMemoryError: Java heap space
错误:java堆溢出。
原因:直接原因是达到了最大堆的容量。导致错误的深层次原因是,可能某些对象的生命期过长或者可能是一直产生对象,并且GC无法回收,引起的内存泄漏。
解决:手动将最大堆的size设置大一些,一般为物理内存的25%,不超过80%。减少对象持有时间过长的现象。
3.java.lang.StackOverflowError
错误:虚拟机栈和本地方法栈溢出。
原因:线程申请的栈的深度大于虚拟机允许的栈的深度;栈扩展时申请内存失败或抛出内存溢出而不是栈溢出。
解决:检查是否递归调用没有出口,或者栈帧过大或者本地变量太多。一般上代码层面的问题较为常见。如果代码层面,实属是内存不够引起的,减少线程或者使用更高配置的电脑(64位,128位等)。实在没法了,可以减小最大堆size和最大方法区size。因为最大堆,最大方法区容量,虚拟机栈,本地方法栈共同瓜分了同一线程的内存,比如windows是2G.
4.java.lang.OutOfMemoryError
解决:这个同样是内存溢出,但并没有提示什么具体错误。就有可能是本地直接内存溢出。可以手动设置本地直接内存的大小。

猜你喜欢

转载自blog.csdn.net/Handoking/article/details/84179469