欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

JVM 内存模型与垃圾回收机制

程序员文章站 2022-07-02 14:26:41
在C++中我们需要手动申请内存然后释放内存,否则就会出现对象已经不再使用内存却仍被占用的情况。在Java中JVM内置了垃圾回收的机制,帮助开发者承担对象的创建和释放的工作,极大的减轻了开发的负担。那是不是我们就不需要了解JVM了,显然在做一些优化或者深入研究应用性能的时候,JVM还是起了很关键的作用 ......

在c++中我们需要手动申请内存然后释放内存,否则就会出现对象已经不再使用内存却仍被占用的情况。在java中jvm内置了垃圾回收的机制,帮助开发者承担对象的创建和释放的工作,极大的减轻了开发的负担。那是不是我们就不需要了解jvm了,显然在做一些优化或者深入研究应用性能的时候,jvm还是起了很关键的作用的。

java内存模型结构分为线程共享区和线程私有区

    • 线程共享区:堆、方法区
    • 线程私有区:虚拟机栈、本地方法栈、程序 计数器

    堆:用于存放对象实例和数组,由于堆是用来存放对象实例,因此堆也是垃圾收集器管理的主要区域,故也称为 gc堆。由于现在的垃圾收集器基本都采用分代收集算法,所以堆的内部结构只包含新生代和老年代。
    方法区:用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。
        方法区通常和永久区(perm)关联在一起,但永久代与方法区不是一个概念,只是有的虚拟机用永久代来实现方法区,这样就可以用永久代gc来管理方法区,省去专门内存管理的工作
        根据java虚拟机规范的规定,当方法区无法满足内存分配的需求时,将抛出 outofmemoryerror 异常
    虚拟机栈
        每个方法在执行的时候都会创建一个栈帧,用于存储局部变量表、操作数栈、动态链接、方法出口等信息
        每个方法从调用直至完成的过程,对应一个栈帧在虚拟机栈中入栈到出栈的过程
        局部变量表主要存放一些基本类型的变量和对象句柄,它们可以是方法参数,也可以是方法的局部变量
    程序计数器
      为什么需要程序计数器?
          在多线程情况下,当线程数超过cpu数量或cpu内核数量时,线程之间就要根据时间片轮询抢夺cpu时间资源。也就是说,在任何一个确定的时刻,一个处理器都只会执行一条线程中的指令。因此,为了线程切换后能够恢复到正确的执行位置,每条线程都需要一个独立的程序计数器去记录其正在执行的字节码指令地址
          程序计数器是线程私有的一块较小的内存空间,可以看做是当前线程所执行的字节码的行号指示器
          如果线程正在执行的是一个 java 方法,计数器记录的是正在执行的字节码指令的地址
          如果正在执行的是 native 方法,则计数器的值为空
          程序计数器是唯一一个没有规定任何 outofmemoryerror 的区域

    ---------------------------------jvm 内存模型

JVM 内存模型与垃圾回收机制

 

--- 垃圾回收下次添加,正在学习、消化