jvm各个区域的OOM和

java堆、方法区还有直接内存都可能会出现OOM。
java虚拟机栈和本地方法栈是线程独有的会出现SOF和OOM。
java虚拟机栈存放的是java方法的执行过程里面需要的变量、引用、方法出口等信息。

  • 当栈深度不够而且又无法申请到新的内存来扩展栈的时候就会OOM。
  • 当线程请求的栈深度大于虚拟机所允许的最大深度的时候就会SOF。
  • 当线程请求创建栈的时候内存不够分配那么就会OOM。这里的OOM应该怎么处理,由于没有多余的空间分配给栈了,我们可以想是不是因为给每个线程分配的stack空间太大了,然后导致栈空间不够用导致的;32操作系统内存限定为2g那么,通过参数指定了java堆和方法区的最大值,程序计数器只占用很少的空间,虚拟机本身的内存也不算在内的话剩下的空间就由java虚拟机栈和本地方法栈来共享了,所以每个线程分配的stack越大那么可创建的线程就越少,如果因为创建线程导致了OOM,如果不能减少线程那么可以换成64位机器,如果不能更换64位机器那么只能通过减少java堆区和方法区的大小来增加线程的容量了。

java堆存放的是java对象,是线程共享的区域。

  • 当创建新对象并且堆内存不够去申请内存也申请不下来的时候就会OOM,并且提示java heap space。但是要分析是内存溢出还是内存泄漏,通过Eclipse Memory Analyzer分析如果是内存泄漏,那么可以通过工具查看泄露对象的GC Roots引用链。于是就能找到泄露对象是通过怎样的路径和GC Roots关联的从而导致GC无法回收它,找到泄露对象的类型信息以及GC Roots的引用链就能准确的定位出泄露代码的位置。

方法区存放的是类信息、常量池、静态变量、即时编译后的代码。运行时常量池在方法区。

  • 当运行时常量池需要扩展的时候又申请不到足够的空间那么就会OOM。

猜你喜欢

转载自blog.csdn.net/weixin_42619248/article/details/83900360
今日推荐