JVM(五)

什么是内存溢出,那些区域会发生内存溢出

首先我们要知道java是如何运行一个JVM进程,如下代码

public class Demo3 {
public static void main(String[] args) {
        String message = "hello world";
        System.out.println(message);
    }
}
  1. 首先是写好的代码编译成class文件
  1. 执行java命令
  1. jVM加载你写的类
  1. main线程执行方法
  1. 局部变量进入虚拟机栈
  1. 堆内存创建对象

如上几步,能发生OOM地方

  • metaspace区域用来存放类的信息,如果加载的类信息太多就可能导致OOM
  • 每个线程都有个虚拟机栈,就是所谓的栈内存,这里存放的是方法的里面的局部变量,栈内存大小一般是1m,不断的循环调用方法,就可能导致OOM
  • 堆内存,放一些对象,不断的创建对象,也是可能发生OOM

Metaspace如何触发内存溢出呢

我们用下面参数设置Metaspace内存大小

-XX:MetaspaceSize=512m
-XX:MaxMetaspaceSize=512m

固定512M,当Metaspace满了之后,就会触发FULL GC,回收的条件也比较苛刻,如这个类加载器被回收,这个类的所有对象实例都被回收等等,所以一旦Metaspace满了,未必会回收里面的很多类,一旦回收之后,还是有很多存活的类,如果继续想Metaspace加入更多的类信息,就会导致OOM

导致Metaspace的一般原因如下

  • Metaspace的值太小,只有几十MB,(一般系统512MB)当对于一个稍微大型的系统,由于他有许多的类信心,就可能导致Metaspace不够用
  • 有很多系统用cgLIB之类的技术动态生成一些类,一旦代码没有控制住,就会创建过多的类,容易把Metaspace给塞满,进而引发内存溢出

虚拟机栈溢出

我们知道一个线程的虚拟机栈的内存大小是固定的,一般默认是1MB,正如我们之前讲的main()方法,就会产生一个main的栈帧,如下代码

public class Demo3 {
public static void main(String[] args) {
        String message = "hello world";
        System.out.println(message);
        sayHello("我是肉丝");
    }    
public static  void sayHello(String name){
        System.out.println("你好,杰克"+name);
    }
}

每一个方法的调用,都会在虚拟机栈中创建一个栈帧,保存对应的局部变量,但是此时我们要注意的是每一个帧栈也是要占内存的,虽然一些变量和其他的对象数据占不了太大的内存,但是实际上也是要占用的,

如果一个线程不断的调用各种方法,不停的把方法的栈帧压入虚拟机栈,就会不断的占用这个线程1MB的栈内存,最终会导致栈内存溢出

什么情况下会发生栈内存溢出呢

public static  void sayHello(String name){
        sayHello(name);
    }

如上代码,出现这种不断递归调用,就有可能导致栈内存溢出,一般来说不会导致栈内存溢出,除非你的bug才会导致

堆内存溢出

  1. 首先平时我们系统不断创建对象,然后大量的对象进入Eden区,一旦Eden区满之后,就会发生一次YGC,然后存活对象进入S区
  1. 一旦高并发场景,ygc后很多请求还没有处理完毕,存活对象很多,S区,放不下,就会进入老年代
  1. 一旦老年代满了,就会发生FULL gc
  1. 不幸的是老年代GC之后,还是有很多对象存活,此时年轻代不断不断GC,把存活的对象转移到老年代,但是老年代也空间不足了

最终就会由于堆内存实在放不下对象,导致内存溢出,JVM崩溃

一般什么场景会导致堆内存溢出呢

  • 系统承载高并发,因为请求量过大,导致大量对象存活,所以要继续放入新的对象实在不行了,就会引起OOM
  • 系统内存泄露,就莫名其妙弄很多对象,结果对象都是存活的,没有及时取消他的引用,就会导致GC无法回收,引发内存泄漏最终OOM

本文分享自微信公众号 - 洁癖是一只狗(rookie-dog),作者:洁癖汪

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2021-08-23

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 一文简述JVM五腹六脏!

    Java作为一种面向对象的,跨平台语言,其对象、内存等一直是比较难的知识点。而且很多概念的名称看起来又那么相似,很多人会傻傻分不清楚。比如本文我们要讨论的JVM...

    用户1667431
  • JVM 《五 JVM 类加载机制&Tomcat 类加载方式解析》

    所谓类加载机制也就是Java 虚拟机从磁盘装载 .class 文件或者网络中二进制字节流并且加载Java类的方式或者过程。

    邹志全
  • JVM(五)垃圾回收器的前世今生

    如果垃圾回收的算法属于内存回收的方法论的话,那本文讨论的垃圾回收器就属于内存回收的具体实现。

    Java中文社群-磊哥
  • 深入理解JVM(五)——HotSpot垃圾收集器详解

    HotSpot虚拟机提供了多种垃圾收集器,每种收集器都有各自的特点,没有最好的垃圾收集器,只有最适合的垃圾收集器。我们可以根据自己实际的应用需求选择最适合的垃...

    大闲人柴毛毛
  • JVM笔记五-堆区

    在JVM中,堆区是重中之重。通过前面文章的学习,我们知道了,栈区是不会有垃圾回收的,所以,经常说的垃圾回收,其实就是回收的是堆区的数据。在这里,我们将会看到传说...

    凯哥Java
  • jvm系列(五):Java GC 分析

    Java GC就是JVM记录仪,书画了JVM各个分区的表演。 什么是 Java GC Java GC(Garbage Collection,垃圾收集,垃圾回收)...

    纯洁的微笑
  • JVM系列五(javac 编译器).

    我们都知道 *.java 文件要首先被编译成 *.class 文件才能被 JVM 认识,这部分的工作主要由 Javac 来完成,类似于 Javac 这样的我们称...

    JMCui
  • JVM技术总结之五——JVM逃逸分析

    一个对象(或变量)在方法中处理完毕返回时,返回结果可能会被其他对象引用,或者全局引用,这种现象即为逃逸。或者可以说,一个对象指针被多个线程或方法引用时,该对象指...

    剑影啸清寒
  • JVM 学习笔记(五)

      前面的文件介绍了JVM的内存模型以及各个区域存放了那些内容,本编文章将介绍JVM中的垃圾回收Garbage Collector,和大家一起探讨一下。

    会说话的丶猫
  • Java虚拟机(五):JVM调优命令

    运用jvm自带的命令可以方便的在生产监控和打印堆栈的日志信息帮忙我们来定位问题!虽然jvm调优成熟的工具已经有很多:jconsole、大名鼎鼎的VisualVM...

    朝雨忆轻尘
  • 用Java实现JVM第五章《指令集和解释器》

    案例介绍 本案例通过java代码实现jvm规范中指令集和解释器,完成后就可以开始执行1到100的加和计算。

    小傅哥
  • 用Java实现JVM第五章《指令集和解释器》

    本案例通过java代码实现jvm规范中指令集和解释器,完成后就可以开始执行1到100的加和计算。

    小傅哥
  • jvm源码解析(五)synchronized和ReentrantLock

    一、Synchronized和ReentrantLock是怎么实现的,他们有什么区别

    用户6203048
  • 《深入理解Java虚拟机》(五)JVM调优 - 工具

    JVM调优 - 工具 JConsole:Java监视与管理控制台 JConsole是一个机遇JMX(Java Management Extensions,即Ja...

    搜云库
  • 简述JVM基础(五):虚拟机类加载机制

    我们一定心里有个疑问,我们那个多态是怎么回事?我们指定的一个接口,却可以等到运行时可以对应于不同的实现类。这是因为,Java有个特性就是依赖运行期动态加载和动态...

    open
  • Java虚拟机详解(五)------JVM参数(持续更新)

      JVM参数有很多,其实我们直接使用默认的JVM参数,不去修改都可以满足大多数情况。但是如果你想在有限的硬件资源下,部署的系统达到最大的运行效率,那么进行相关...

    IT可乐
  • JVM系列十五(对象分配注意项).

    这个几乎不用解释,减少了内存的使用量,自然就减少 GC 回收时的压力,同时降低了内存碎片与 CPU 的使用量。在设计对象时,应仔细检查并问自己:

    JMCui
  • 【JVM进阶之路】五:垃圾回收概述和对象回收判定

    垃圾收集(Garbage Collection,简称GC)简单说,就是要干三件事:

    三分恶
  • 「每日五分钟,玩转 JVM」:GC 概览

    GC(Garbage Collection)是我们在学习 JVM 的过程中不可避免的一道坎,接下来,我们就来系统的学习一下 GC。

    山禾说

扫码关注云+社区

领取腾讯云代金券