1)JVM区域划分与溢出异常

    java与C++之间有一堵内存动态分配和垃圾收集技术所围成的高墙,墙外的人想进去,墙里的人却想出来。    --摘自《深入理解Java虚拟机》
    C++认为内存很重要,所以一定要给人管理,java同样认为内存很重要,所以一定不能给人管理。    --忘了哪看来的
    计算机的世界中,所有问题都可以通过引入一个中间角色来解决(jvm就是典型)。 
 
    a.为什么做内存划分?
    java进程下的占用的一块内存,划分成5个逻辑空间,对每一块做特定的处理数据方式和内存管理方式,会大大提升内存效率。
    

 
     b.划分情况
    上边提到的5个内存空间分别为
    栈、堆、方法区、程序计数器、本地方法栈 (注:此逻辑为划分规范,即各个JVM虚拟机(eg : HotSpot和此规范可理解为接口和实现类的关系)实现需参考此规范)   
    堆:所有几乎所有new出来的东西,GC的主要作案地点非常血腥,然而真实情况是随着新技术方案的出现未必所有new的对象都会在堆申请内存,后面展开讨论。
  1. Exception in thread “main”: java.lang.OutOfMemoryError: Java heap space
          (对象不能分配在堆中,可能程序出现死循环)    
 
    栈:存放的是一个个方法对应的栈桢,而各个栈桢存的是局部变量表、操作数栈、动态链接、方法出口,方法调用链结束对应栈桢压栈和弹栈,线程结束当前栈销毁。
          此区域会出现两种OOM情况StackOverflowError:线程请求的栈深度大于虚拟机所允许的深度;OutOfMemoryError:当扩展时无法申请到足够的内存(当前大部分的虚拟机        都会动态扩展,然而单线程情况下只能实验出StackOverflowError异常)
          Exception in thread "main" java.lang.StackOverflowError
    
    方法区:虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等
           JDK8后此区域的hotspot实现由永久带换为元空间 
  1. Exception in thread “main”: java.lang.OutOfMemoryError: PermGen space
          (类或者方法不能被加载到老年代。它可能出现在一个程序加载很多类的时候,比如引用了很多第三方的库、或者使用了类似CGlib技术动态生成大量字节码文件)
    
    程序计数器:指向下一条指令的地址,每个线程有一个(唯一无OOM情况的区域)
    
    本地方法栈:native方法,本地实现,当调用native方法时,程序计数器值为undefined
            Exception in thread “main”: java.lang.OutOfMemoryError: unable to create new native thread
           (没有空间给新的线程使用,可看情况适当调小栈大小或堆大小等方法换取更多有效线程并发)
 
    还有几种OOM异常不再逐个列举,重点只需对异常产生区域和原因的理解,来快速排查及做出相应策略,然而最好的状态是不要给机会让OOM出现,做好合理架构和监控。


 
   还有一块不在JVM规范中的堆外内存,也称作直接内存。
    NIO中一般使用直接内存与外界通讯并作为缓存使用,目的是避免在java堆和native堆来回复制数据,速度快。
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值