目录

Java 栈(Stack)

Java 堆(Heap)

堆 (Heap) VS 栈 (Stack)

常见 OOM  原因及解决方案


本文可以结合《 Sun JVM 内存管理、GC 工作流程、JVM 参数与调优》、《JVM 规范与 Sun JVM 实现、运行时数据区域、垃圾分代回收算法》查看。

JVM 整体架构图

Java 栈(Stack)

1、Java 栈是与每一个线程关联的,JVM 在创建每一个线程的时候,会分配一定的栈空间给线程,Java Stack 为每个线程独享。

2、Java Stack 主要用来存储线程执行过程中的局部变量,方法的返回值,以及方法调用上下文(对象的引用), 以帧为单位保存线程的运行状态。

3、栈空间随着线程的终止而释放。

4、StackOverflowError:如果在线程执行的过程中,栈空间不够用,那么 JVM 就会抛出此异常,这种情况一般是死递归造成的。

Java 堆(Heap)

1、Java 中堆是由所有的线程共享的一块内存区域,堆用来保存各种 JAVA 对象,比如数组,线程对象等。

2、JVM 堆一般又可以分为以下三部分:

这里也可以参考《 Sun JVM 内存管理、GC 工作流程、JVM 参数与调优》

Perm(永久区) 1、Perm 代主要保存 class(类,包括接口等),method(方法),filed(属性) 等元数据,这部分的空间一般不会溢出,除非一次性加载了很多的类,不过在涉及到热部署的应用服务器的时候,有时候会遇到 java.lang.OutOfMemoryError : PermGen space 的错误,造成这个错误的很大原因就有可能是每次都重新部署,但是重新部署后,类的 class 没有被卸载掉,这样就造成了大量的 class 对象保存在了 perm 中,这种情况下,一般重新启动应用服务器可以解决问题。
Tenured(年老代) 1、Tenured 区主要保存生命周期长的对象,一般是一些老的对象,当一些对象在 Young 复制转移一定的次数以后,对象就会被转移到 Tenured 区,一般如果系统中用了 application 级别的缓存,缓存中的对象往往会被转移到这一区间。
Young(年轻代)

1、Young 区被划分为三部分,Eden(伊甸园) 区和两个大小严格相同的 Survivor(幸存者)区,其中 Survivor 区间中,某一时刻只有其中一个是被使用的,另外一个留做垃圾收集时复制对象用。

2、在 Young 区间变满的时候,minor GC 就会将存活的对象移到空闲的 Survivor 区间中,根据 JVM 的策略,在经过几次垃圾收集后,任然存活于 Survivor 的对象将被移动到 Tenured 区间。

堆 (Heap) VS 栈 (Stack)

1、Java 中用堆来存储对象,一旦堆中的对象被销毁,继续引用这个对象的话,就会出现著名的 NullPointerException。

2、栈没有堆灵活,但是更严格,是安全的,易于管理,因为只要上面的引用没有销毁,下面引用就一定还在,所以,在栈中,上面引用永远可以通过下面引用来查找对象,同时如果确认某一区间的内容会一起存在、一起销毁,也可以上下互相引用。

3、在大部分程序中,都是先定义的变量、引用先进栈,后定义的后进栈,同时,区块内部的变量、引用在进入区块时压栈,区块结束时出栈,理解了这种机制,就可以很方便地理解各种编程语言的作用域的概念了。

栈:存放变量引用的地方,以及基本数据类型

堆:存放实际对象的地方,即数组、线程对象等。

举例说明
int i = 7; 存在栈里边的,内容为 i = 7。

String s = "Hello World!"; 这个是存在另外一块静态代码区。

Apple app = new Apple(); app 引用存在栈里,引用地址对应对象 Apple 在堆里。

常见 OOM  原因及解决方案

1、当 JVM 内存严重不足时,就会抛出 java.lang.OutOfMemoryError 错误

一)Java heap space

1、当堆内存(Heap Space)没有足够空间存放新创建的对象时,就会抛出 java.lang.OutOfMemoryError:Javaheap space 错误.

2、Javaheap space 错误产生的常见原因可以分为以下几类:

1、请求创建一个超大对象,通常是一个大数组。

2、超出预期的访问量/数据量,通常是上游系统请求流量飙升,常见于各类促销/秒杀活动,可以结合业务流量指标排查是否有尖状峰值。

3、过度使用终结器(Finalizer),该对象没有立即被 GC。

4、内存泄漏(Memory Leak),大量对象引用没有释放,JVM 无法对其自动回收,常见于使用了 File 等资源没有回收。

3、针对大部分情况,通常只需要通过 -Xmx 参数调高 JVM 堆内存空间即可,如果仍然没有解决,可以参考以下情况做进一步处理:

1、如果是超大对象,可以检查其合理性,比如是否一次性查询了数据库全部结果,而没有做结果数限制。

2、如果是业务峰值压力,可以考虑添加机器资源,或者做限流降级。

3、如果是内存泄漏,需要找到持有的对象,修改代码设计,比如关闭没有释放的连接。

2)GC overhead limit exceeded

1、当 Java 进程花费 98% 以上的时间执行 GC,但只恢复了不到 2% 的内存,且该动作连续重复了 5 次,就会抛出 java.lang.OutOfMemoryError:GC overhead limit exceeded 错误。

2、简单地说,就是应用程序已经基本耗尽了所有可用内存, GC 也无法回收,此类问题的原因与解决方案跟 Javaheap space 类似。

三)Permgen space

1、该错误表示永久代(Permanent Generation)已用满,通常是因为加载的 class 数目太多或体积太大。

2、永久代存储对象主要包括以下几类:

1、加载/缓存到内存中的 class 定义,包括类的名称,字段,方法和字节码;

2、常量池;

3、对象数组/类型数组所关联的 class;

4、JIT 编译器优化后的 class 信息。

3、PermGen 的使用量与加载到内存的 class 的数量/大小正相关。

4、根据 Permgen space 报错的时机,可以采用不同的解决方案,如下所示:

1、程序启动报错,修改 -XX:MaxPermSize 启动参数,调大永久代空间。

2、应用重新部署时报错,很可能是应用没有重启,导致加载了多份 class 信息,只需重启 JVM 即可解决。

3、运行时报错,应用程序可能会动态创建大量 class,而这些 class 的生命周期很短暂,但是 JVM 默认不会卸载 class,可以设置 -XX:+CMSClassUnloadingEnabled-XX:+UseConcMarkSweepGC 这两个参数允许 JVM 卸载 class。

四)Metaspace

1、JDK 1.8 使用 Metaspace 替换了永久代(Permanent Generation),该错误表示 Metaspace 已被用满,通常是因为加载的 class 数目太多或体积太大。

2、此类问题的原因与解决方法跟 Permgenspace 非常类似,可以参考上文。需要特别注意的是调整 Metaspace 空间大小的启动参数为 -XX:MaxMetaspaceSize

JVM 堆、栈概述 与 常见 OOM 原因及解决方案相关推荐

  1. 悬浮细胞、淋巴细胞培养常见失败原因及解决方案

    一.严格无菌操作 对实验室以及培养过程中所接触的试剂.液体.器皿.仪器的消毒,均应严格按照有关细胞培养的参考书的要求进行操作.无菌观念要贯穿整个实验的始终,不可松懈. 二.培养器皿的选择 淋巴细胞培养 ...

  2. JVM堆 栈 方法区详解

    一.栈 每当启用一个线程时,JVM就为他分配一个JAVA栈,栈是以帧为单位保存当前线程的运行状态 栈是由栈帧组成,每当线程调用一个java方法时,JVM就会在该线程对应的栈中压入一个帧 只有在调用一个 ...

  3. ChatGPT 常见错误原因及解决方案:报错、回答不完整、网络错误等

    最近,由人工智能实验室 OpenAI 发布的对话式大型语言模型 ChatGPT 火得一塌糊涂.它可以与人类轻松地对话,无论是多么奇葩的问题 ChatGPT 都不在话下.在体验 ChatGPT 的同时我 ...

  4. 常见的 OOM 原因及其解决方法(OutOfMemoryError)

    当 JVM 内存严重不足时,就会抛出 java.lang.OutOfMemoryError 错误.本文总结了常见的 OOM 原因及其解决方法,如下图所示.如有遗漏或错误,欢迎补充指正. 1.Java ...

  5. javaheapspace解决方案_高手总结的9种 OOM 常见原因及解决方案

    当 JVM 内存严重不足时,就会抛出 java.lang.OutOfMemoryError 错误.本文总结了常见的 OOM 原因及其解决方法,如下图所示.如有遗漏或错误,欢迎补充指正. 1.Java ...

  6. 九种 OOM 常见原因及解决方案(IT枫斗者)

    九种 OOM 常见原因及解决方案(IT枫斗者) 什么是OOM? OOM,全称"Out Of Memory",翻译成中文就是"内存用完了",来源于java.lan ...

  7. Java JVM堆空间的概述

    Java JVM堆空间的概述 1.设置堆空间初始值和最大值 2.堆的核心概述 内存细分 3.堆空间大小的设置 4.新生代与老年代 5.图解对象分配的过程 6.常用调优工具 7.Minor GC.Maj ...

  8. 高手总结的9种 OOM 常见原因及解决方案

    高手总结的9种 OOM 常见原因及解决方案 [强制]线程池不允许使用 Executors 去创建,而是通过 ThreadPoolExecutor 的方式,这样 的处理方式让写的同学更加明确线程池的运行 ...

  9. JVM内存参数设置及常见错误总结

    一.  JVM规范 JVM规范对Java运行时的内存划定了几块区域(详见这里),有:JVM栈(Java Virtual Machine Stacks).堆(Heap).方法区(Method Area) ...

  10. Java程序员必备:常见OOM异常分析

    前言 放假这几天,温习了深入理解Java虚拟机的第二章, 整理了JVM发生OOM异常的几种情况,并分析原因以及解决方案,希望对大家有帮助.    Java 堆溢出 Java堆用于存储对象实例,只要不断 ...

最新文章

  1. CREATE TABLESPACE
  2. 【 MATLAB 】Fourier Transforms ( fft )
  3. FIFOQueue '_4_batch_processing/batch_join/fifo_queue' is closed and has insu
  4. python中保留小数_python保留小数位的三种实现方法
  5. failed to get the task for process XXX(解决方案)
  6. Oracle中如何删除某个用户下的所有数据的方法
  7. Ubantu18.04安装Vivado
  8. 3DMax插件和它的3DXI接口
  9. C语言 将整数写入内存指定的连续字节单元中
  10. 数据科学与大数据技术的案例_主数据科学案例研究,招聘经理的观点
  11. HTTPS加密传输过程
  12. 虹软人脸识别在 linux中so文件加载不到的问题
  13. “谷歌杀手”发明者,科学天才 Wolfram
  14. C++ typename 的双重含义
  15. IOS UIwebView 加载网络图片 使用相对地址
  16. 用Wineskin在Mac上运行exe文件
  17. 观天涯kk大神10年帖子有感
  18. Python爬取手机号码前7位号段归属地及运营商
  19. Linux基础知识介绍
  20. Oracle中rowid的用法(全面)

热门文章

  1. 接口和抽象类的区别(转载)
  2. (Oracle、SqlServer、Access)数据库开发代码生成工具SharpCode2.0
  3. cout和printf的区别
  4. mysql left join_对比MySQL,教你在Pandas中实现SQL常用操作!
  5. 拓端tecdat|R语言Black Scholes和Cox-Ross-Rubinstein期权定价模型案例
  6. 拓端tecdat|R语言中使用多重聚合预测算法(MAPA)进行时间序列分析
  7. 拓端tecdat|Stata估算观测数据的风险比
  8. 拓端tecdat|R语言中实现层次聚类模型
  9. 【大数据部落】R语言实现:混合正态分布EM最大期望估计法
  10. R语言周氏检验(Chow test) 检验回归中结构不稳定性的虚拟变量的替代方案