icode icode
首页
  • Android学习

    • 📁基础内容
    • 📺AndroidCore
    • 🎨Android-UI
    • 🏖️Components
    • 📊Fragment
    • 🔗网络操作
    • 🔏异步机制
    • 📦数据存储
    • 🗃️Gradle
  • 学习笔记

    • 『框架』笔记
    • 『Kotlin』笔记
    • 《Vue》笔记
    • 《Git》学习笔记
    • 『Bug踩坑记录』
  • ListView
  • RecyclerView
  • ViewPager
  • Java笔记

    • 🟠JavaSE
    • 🟢JavaWeb
    • 🔴JavaEE
    • ⚪JavaTopic
    • 🍳设计模式
  • 计算机基础

    • 📌计算机网络
    • 🔍数据结构
    • 📦数据库
    • 💻OS
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
  • 关于

    • 📫关于我
  • 收藏

    • 网站
    • 资源
    • Vue资源
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

iqqcode

保持对技术的探索实践与热爱
首页
  • Android学习

    • 📁基础内容
    • 📺AndroidCore
    • 🎨Android-UI
    • 🏖️Components
    • 📊Fragment
    • 🔗网络操作
    • 🔏异步机制
    • 📦数据存储
    • 🗃️Gradle
  • 学习笔记

    • 『框架』笔记
    • 『Kotlin』笔记
    • 《Vue》笔记
    • 《Git》学习笔记
    • 『Bug踩坑记录』
  • ListView
  • RecyclerView
  • ViewPager
  • Java笔记

    • 🟠JavaSE
    • 🟢JavaWeb
    • 🔴JavaEE
    • ⚪JavaTopic
    • 🍳设计模式
  • 计算机基础

    • 📌计算机网络
    • 🔍数据结构
    • 📦数据库
    • 💻OS
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
  • 关于

    • 📫关于我
  • 收藏

    • 网站
    • 资源
    • Vue资源
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • JavaSE

    • 面向对象

    • 常用API

    • 集合类

    • 多线程

    • JDK8新特性

    • IO流

    • JVM

      • 类加载系统
      • 运行时数据区及线程
      • 程序计数器
      • 虚拟机栈
      • 本地方法栈
      • 堆
      • 方法区
      • 对象实例化的内存布局与访问定位
      • 面试考点
      • 垃圾回收算法
      • 执行引擎
      • 垃圾回收相关概念
      • 垃圾回收算法
      • 垃圾回收器
      • GC日志分析
      • JVM内存区域与内存溢出异常
        • JVM垃圾回收器与内存分配策略
        • Java内存模型JMM详解
        • StringTable详解
        • 站在虚拟机栈的角度,用字节码来理解i++和++i
    • JavaWeb

    • JavaEE

    • JavaTopic

    • 设计模式

    • 计算机基础

    • Java后端
    • JavaSE
    • JVM
    iqqcode
    2021-06-17
    目录

    JVM内存区域与内存溢出异常

    # 1. JVM简介

    虚拟机简介 :JVM(Java Virtual Machine的简称,意为Java虚拟机)

    虚拟机 :指通过软件模拟的具有完整硬件功能的、运行在一个完全隔离的环境中的完整计算机系统

    常见的虚拟机 :JVM、VMwave、Virtual Box

    PS: Java虚拟机并不是只能跑Java程序,只要是符合JVM的运行规范的语言,在编译后都可由JVM来解释执行,如Scala、Kotlin、JRuby等。

    Java虚拟机特点:

    • 一次编译,到处运行

    • 自动内存管理

    • 自动垃圾回收功能

    # 2. JVM内存区域划分

    JVM内存区域划分 ---- 6大区域

    在这里插入图片描述

    # 线程私有内存

    程序计数器、虚拟机栈、本地方法栈

    什么是线程私有?

    由于JVM的多线程是通过线程轮流切换并分配处理器执行时间的方式来实现,因此在任何一个确定的时刻,一个处理器(多核处理器则指的是一个内核)都只会执行一条线程中的指令。因此为了切换线程后能恢复到正确的执行位置,每条线程都需要独立的程序计数器,各条线程之间计数器互不影响,独立存储。我们就把类似这类区域称之为"线程私有"的内存。

    线程私有 :

    • 程序计数器、虚拟机栈、本地方法栈的生命周期与线程的生命周期完全相同;
    • 随着线程的创建而创建,随着线程的销毁而回收.
    • 不同线程这三块内存彼此隔离.
    # I. 程序计数器 :

    程序计数器是一块比较小的内存空间,可以看做是当前线程所执行的程序的行号指示器

    程序计数器内存区是JVM中唯一 一个没有规定任何OOM(Out-Of-MemoryError)异常的区域!

    • 如果当前线程正在执行的是一个Java方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址;
    • 若执行的是native方法,计数器值为0

    微机原理 中断响应 (opens new window)

    我们来回顾一下CPU对中断的响应 :

    大二上学期学的微机原理,早忘光了 在这里插入图片描述 在这里插入图片描述

    这里的程序计数器就类似于保留现场、保护断点这一操作,当CPU响应中断时,会把断点记录在一个寄存器中,转而去响应中断. 而在JVM中,程序计数器充当了这一角色,我们就把程序计数器存放数据的这一区域称之为"线程私有"内存.

    # II. 虚拟机栈 :

    虚拟机栈描述的是Java ==方法执行的内存模型==

    • 每个方法执行的同时都会创建一个栈帧用于存储==局部变量表、操作数栈、动态链接、方法出口==等信息

    • 每一个方法从调用到执行完成的过程,就对应一个栈帧在虚拟机栈中入栈和出栈的过程

    在这里插入图片描述

    在这里插入图片描述

    局部变量表 : 存放了编译器可知的各种基本数据类型(8大基本数据类型)、对象引用

    • -Xss设置栈容量

    此区域一共会产生以下两种异常 :

    1. 如果线程请求的栈深度大于虚拟机所允许的深度(-Xss设置栈容量),将会抛出StackOverFlowError异常
    2. 虚拟机在==动态扩容==时无法申请到足够的内存,会抛出OOM(OutOfMemoryError)异常

    OOM产生的原因:

    内存泄露 :参生的对象永远无法被垃圾回收器回收

    内存溢出 :当前堆的空间过小,没有足够空间容纳新的对象(适当的将堆的大小适当扩大)

    # III. 本地方法栈

    native方法的内存模型

    HotSpot : (Java默认的虚拟机) 本地方法栈与虚拟机栈合二为一

    # 线程共享内存

    线程共享 : 所有线程共享Java堆、方法区、运行时常量池这三块内存,彼此不隔离

    # I. Java堆
    • Java堆(Java Heap)是JVM所管理的最大内存区域,所有的对象实例以及数组都要在堆上分配
    • Java堆是==垃圾回收器==的主要区域(GC堆),Java堆可以处在物理上不连续的内存空间中
    • Java堆在虚拟机中都是可扩展的(-Xmx设置堆的最大值,-Xms设置最小值)
    • 堆中没有足够的内存完成实例分配且堆无法再拓展时,会抛出OOM异常

    JVM产生OOM的原因:

    • 栈:虚拟机在动态扩容时无法申请到足够的内存
    • 堆:堆中没有足够的内存完成实例分配且堆无法再拓展时
    # II. 方法区
    • 存储 被JVM加载的类信息、常量、静态变量、编译后的代码等.
    • 方法区也被称为"永久代"(JDK8已经被元空间取代)
    # III. 运行时常量池

    运行时常量池是方法区的一部分,存放字面量与符号引用

    字面量 : 字符串、final常量、基本数据类型的值(直接写出来的值)

    符号引用 : 拿着符号引用能够找到具体的类或方法

    下一节 : JVM(二)垃圾回收器与内存分配策略 (opens new window)

    编辑 (opens new window)
    上次更新: 2021/06/27, 10:49:09
    GC日志分析
    JVM垃圾回收器与内存分配策略

    ← GC日志分析 JVM垃圾回收器与内存分配策略→

    最近更新
    01
    匿名内部类
    10-08
    02
    函数式接口
    10-08
    03
    ARouter-Kotlin踩坑
    10-05
    更多文章>
    Theme by Vdoing | Copyright © 2021-2023 iqqcode | MIT License | 备案号-京ICP备2021028793号
    • 跟随系统
    • 浅色模式
    • 深色模式
    • 阅读模式
    ×