您的位置 首页 java

JVM哪些区域会OOM内存溢出?

程序员最怕线上出事故,一旦有Case,就会有程序员被拉出去祭天,这是网上常见的一个段子。

最常遇到的故障:OOM

先不考虑自己系统外部依赖的缓存、消息队列、数据库等挂掉,最常见的挂掉的原因是什么?就是OOM,即内存溢出!

你的JVM内存就这么点,结果你拼命的往里面塞东西,结果内存塞不下了,不就直接溢出了吗?

内存溢出这个问题可能对你的系统是毁灭性的打击,他代表你的JVM内存不足以支撑你的代码的运行。所以一旦发生这个情况,就会导致你的系统直接停止运转,甚至会导致你的JVM进程直接崩溃掉,进程都没了! 用户突然发现很奇怪,为什么点击APP、点击网页,都没反应?

然后大量的投诉和反馈给到客服,客服直接转移投诉给到运营,运营会直接反馈给技术人员。

这个时候技术人员往往得知这个消息会直接目瞪口呆,最害怕的事情发生了,自己负责的线上系统居然挂掉了,今年年终奖没了,弄不好还得提前出去找工作。

如何处理OOM

为什么会突然OOM?系统代码到底产生了多少对象?为什么会产生这么多对象?JVM为什么会放不下这么多对象?到底怎么去排查这个问题?又如何解决呢?

启动一个Java系统,本质就是启动一个JVM进程,我们写好的代码他都是后缀为“.java”的源代码,这代码是不能运行的。

第一步就是这份 .java 源代码文件必须先 编译 .class 字节码文件,这才可运行。

接着对这种编译好的字节码文件,如 HelloWorld.class ,若里面包含main方法,就能用“java命令”在命令行执行该字节码文件。一旦执行“java命令”,相当于启动一个JVM进程:负责执行你写好的那些代码。

到底执行哪些代码:JVM得加载你写的类

JVM进程怎么执行你写的那些代码呢?Java是面向对象语言,最基本代码组成单元就是类。

然后在一个一个的类里我们会定义各种变量,方法,数据结构,通过if else之类的语法,写出来各种各样的系统业务逻辑,这就是所谓的编程。

所以JVM既然要执行你写的代码,首先当然得把你写好的类加载到内存里来啊!

所以JVM有个永久代,1.8后都叫Metaspace了,用来存放系统里的各种类的信息,包括JDK自身内置的一些类的信息。

JVM有类加载器和一套类加载机制,他负责把我们写好的类从编译好的“.class”字节码文件里加载到内存。

JVM哪些区域会OOM内存溢出?

既然Metaspace存放类信息的, 是不是有可能在Metaspace里就会发生OOM? 是的!

Java虚拟机栈:让线程执行各种方法

那些Java代码虽然是一个一个的类,但核心代码逻辑一般都封装在类里面的各种方法。

如JVM已加载HelloWorld类到内存,接着怎么执行他里面的代码?JVM进程总是从main方法开始执行。JVM进程里的谁去执行main()方法?

所有方法执行,都依赖JVM进程中的某个线程去执行,你可以理解为线程才是执行我们写的代码的核心主体。

JVM进程启动后,默认就有个main线程,负责执行main()方法:

JVM哪些区域会OOM内存溢出?

这些方法里的局部变量可放在哪呢?每个线程都有一个自己的虚拟机栈,就是所谓的栈内存。

这线程只要执行一个方法,就会为方法创建一个栈桢,将栈桢放入自己的虚拟机栈,然后在这栈桢里放入方法中定义的各种局部变量:

JVM哪些区域会OOM内存溢出?

我们可以设置JVM中每个线程的虚拟机栈的内存大小的,一般1MB。既然每个线程的虚拟机栈内存大小固定,所以也可能会发生虚拟机栈内存溢出。

堆内存:放我们创建的各种对象

一些方法中可能频繁创建各种对象,这些对象都是放在堆:

通常我们在JVM中分配给堆内存的空间其实一般是固定的,若不停在堆里创建对象,也有可能会发生内存溢出。

文章来源:智云一二三科技

文章标题:JVM哪些区域会OOM内存溢出?

文章地址:https://www.zhihuclub.com/183853.shtml

关于作者: 智云科技

热门文章

网站地图