Java中的OutOfMemoryError和JVM内存结构

Java中的OutOfMemoryError和JVM内存结构

ID:38104021

大小:86.00 KB

页数:4页

时间:2019-06-06

Java中的OutOfMemoryError和JVM内存结构_第1页
Java中的OutOfMemoryError和JVM内存结构_第2页
Java中的OutOfMemoryError和JVM内存结构_第3页
Java中的OutOfMemoryError和JVM内存结构_第4页
资源描述:

《Java中的OutOfMemoryError和JVM内存结构》由会员上传分享,免费在线阅读,更多相关内容在行业资料-天天文库

1、转自liuchangit.comOutOfMemoryError在开发过程中是司空见惯的,遇到这个错误,新手程序员都知道从两个方面入手来解决:一是排查程序是否有BUG导致内存泄漏;二是调整JVM启动参数增大内存。OutOfMemoryError有好几种情况,每次遇到这个错误时,观察OutOfMemoryError后面的提示信息,就可以发现不同之处,如:java.lang.OutOfMemoryError:Javaheapspacejava.lang.OutOfMemoryError:unabletocreatenewnativethreadjav

2、a.lang.OutOfMemoryError:PermGenspacejava.lang.OutOfMemoryError:RequestedarraysizeexceedsVMlimit虽然都叫OutOfMemoryError,但每种错误背后的成因是不一样的,解决方法也要视情况而定,不能一概而论。只有深入了解JVM的内存结构并仔细分析错误信息,才有可能做到对症下药,手到病除。 JVM规范JVM规范对Java运行时的内存划定了几块区域(详见这里),有:JVM栈(JavaVirtualMachineStacks)、堆(Heap)、方法区(Meth

3、odArea)、常量池(RuntimeConstantPool)、本地方法栈(NativeMethodStacks),但对各块区域的内存布局和地址空间却没有明确规定,而留给各JVM厂商发挥的空间。 HotSpotJVMSun自家的HotSpotJVM实现对堆内存结构有相对明确的说明。按照HotSpotJVM的实现,堆内存分为3个代:YoungGeneration、Old(Tenured)Generation、PermanentGeneration。众所周知,GC(垃圾收集)就是发生在堆内存这三个代上面的。Young用于分配新的Java对象,其又被

4、分为三个部分:EdenSpace和两块SurvivorSpace(称为From和To),Old用于存放在GC过程中从YoungGen中存活下来的对象,Permanent用于存放JVM加载的class等元数据。详情参见HotSpot内存管理白皮书。堆的布局图示如下: 根据这些信息,我们可以推导出JVM规范的内存分区和HotSpot实现中内存区域的对应关系:JVM规范的Heap对应到Young和OldGeneration,方法区和常量池对应到PermanentGeneration。对于Stack内存,HotSpot实现也没有详细说明,但HotSpot

5、白皮书上提到,Java线程栈是用宿主操作系统的栈和线程模型来表示的,Java方法和native方法共享相同的栈。因此,可以认为在HotSpot中,JVM栈和本地方法栈是一回事。 操作系统由于一个JVM进程首先是一个操作系统进程,因此会遵循操作系统进程地址空间的规定。32位系统的地址空间为4G,即最多表示4GB的虚拟内存。在Linux系统中,高地址的1G空间(即0xC0000000~0xFFFFFFFF)被系统内核占用,低地址的3G空间(即0×00000000~0xBFFFFFFF)为用户程序所使用(显然JVM进程运行在这3G的地址空间中)。这3G

6、的地址空间从低到高又分为多个段;Text段用于存放程序二进制代码;Data段用于存放编译时已初始化的静态变量;BSS段用于存放未初始化的静态变量;Heap即堆,用于动态内存分配的数据结构,C语言的malloc函数申请的内存即是从此处分配的,Java的new实例化的对象也是自此分配。不同于前面三个段,Heap空间是可变的,其上界由低地址向高地址增长。内存映射区,加载的动态链接库位于这个区中;Stack即栈空间,线程的执行即是占用栈内存,栈空间也是可变的,但它是通过下界从高地址向低地址移动而增长的。详情参见这里。图示如下: JVM本身是由native

7、code所编写的,所以JVM进程同样具有Text/Data/BSS/Heap/MemoryMapping/Stack等内存段。而Java语言的Heap应当是建立在操作系统进程的Heap之上的,Java语言的Stack应该也是建立操作系统进程Stack之上的。综合HotSpot的内存区域和操作系统进程的地址空间,可以大致得到下列图示:Java线程的内存是位于JVM或操作系统的栈(Stack)空间中,不同于对象——是位于堆(Heap)中。这是很多新手程序员容易误解的地方。注意,“Java线程的内存”这个用词不是指Java.lang.Thread对象的

8、内存,java.lang.Thread对象本身是在Heap中分配的,当调用start()方法之后,JVM会创建一个执行单元,最终会创建一

当前文档最多预览五页,下载文档查看全文

此文档下载收益归作者所有

当前文档最多预览五页,下载文档查看全文
温馨提示:
1. 部分包含数学公式或PPT动画的文件,查看预览时可能会显示错乱或异常,文件下载后无此问题,请放心下载。
2. 本文档由用户上传,版权归属用户,天天文库负责整理代发布。如果您对本文档版权有争议请及时联系客服。
3. 下载前请仔细阅读文档内容,确认文档内容符合您的需求后进行下载,若出现内容与标题不符可向本站投诉处理。
4. 下载文档时可能由于网络波动等原因无法下载或下载错误,付费完成后未能成功下载的用户请联系客服处理。