Jvm内存模型与GC垃圾回收

1. 总览

在这里插入图片描述

程序计数器:

当前线程执行的字节码的行号指示器,通过改变此指示器来选取下一个需要执行的字节码指令。
特征:在线程创建时创建、每个线程拥有一个、指向下一条指令的地址

方法区:

jdk1.8之后叫元空间,1.8之前叫永久代。是线程共享的
存储:类信息、常量、静态变量、方法字节码

栈(线程)

是线程私有的,方法在执行时会创建一个栈帧(Stack Frame)用于存储局部变量表、操作数栈、动态链接、方法出口等信息
方法从调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中入栈到出栈的过程。
局部变量表所需的内存空间在编译期间完成分配,而且分配多大的局部变量空间是完全确定的,在方法运行期间不会改变其大小。出栈后空间释放。

是线程共享的,存储对象或数组。

本地方法栈:

存储本地方法(native)的局部变量

程序计数器、(线程)栈、本地方法栈都是每一个线程独有的(线程独享)。

2. 详细解释

示例程序:

package com.tuling.jvm;

public class Math {

    public static final int initData = 666;
    public static User user = new User();

    public int compute(){//一个方法对应一块站栈帧内存区域
        int a = 1;
        int b = 2;
        int c = (a + b)*10;
        return c;
    }

    public static void main(String[] args) {
        Math math = new Math();
        math.compute();
        System.out.println("test");
    }
}

对class文件使用命令javap -c Math.class > Math.txt生成jvm指令码:在这里插入图片描述
部分指令解释:
iconst_1 -> 将int类型常量1压入操作数栈
istore_1 -> 在操作数栈中出栈(1),赋值给局部变量1

执行到4:iload_1,此时程序计数器的值就为4
iload_1 -> 会将局部变量1加载进操作数栈
iadd -> 会把操作数(1和2)出栈,执行相加操作,然后再把结果(3)三压入栈中
bipush 10 -> 把操作数(3)取出,与10做乘操作,再把结果(30)压入操作数栈中
在这里插入图片描述

局部变量表:存放局部变量
操作数栈:存放临时操作数
动态链接:将符号引用转换为直接引用
方法出口:记录上一个方法调用该方法时执行的位置信息,保证方法完成后能回到上一个方法的合适位置继续执行

方法区与堆:

1.方法区里面的静态类型变量如果有对象类型的,该变量是存储的堆中该对象的内存地址(Math中的user指向堆中的user对象)
2.在堆中,每一个对象的对象头里面都有一个class的类型指针指向方法区中的类元信息

在这里插入图片描述
我们new出来的对象一般都放在堆的Eden区中,默认配置中,老年代占堆内存的2/3,年轻代占1/3,年轻代中Eden占8/10,一旦Eden区中放满,会进行minor GC:

minor GC:垃圾收集——把无效的无引用的对象回收掉,把存活的或者有引用的对象放入From区,这些对象的分代年龄加1;
Eden区下一次被放满之后,又会触发minor GC,收集Eden,同时如果From区不为空,也会堆From区域进行回收,把存活下来的对象放入To区域,分代年龄加1;
再一次Eden区被放满之后,又会触发minor GC,对Eden、To区域做垃圾收集,把剩余存活的对象放入From区 ,分代年龄加1…反复运行,如果对象的分代年龄为15之后还没有被销毁,该对象会被移入老年代。

当老年代中放满之后,会进行full GC——对整个堆进行垃圾收集
在进行GC时,会进入STW

Stop-The-World机制简称STW,是在执行垃圾收集算法时,Java应用程序的其他所有线程都被挂起(除了垃圾收集帮助器之外)。

JVM性能调优就是要去减少GC的次数,减少GC的时间

垃圾收集结合实例:

package com.tuling.jvm;

import java.util.ArrayList;

public class HeapTest {

    byte[] a = new byte[1024*100]; //100KB

    public static void main(String[] args) throws InterruptedException {
        ArrayList<Object> heapTests = new ArrayList<>();
        while (true){
            heapTests.add(new HeapTest());
            Thread.sleep(10);
        }
    }
}

使用jdk自带的jvisualvm,安装visul GC插件,可以动态监视进程的情况:
在这里插入图片描述
文中原图链接:https://www.processon.com/view/link/5e82edb3e4b0412013f10583

本文是根据公开课学习整理的笔记…

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
jvm内存模型垃圾回收GC)是Java程序中重要的概念。 Java虚拟机(JVM内存模型定义了Java程序中对象的分配和回收。它包括了堆、栈、方法区和程序计数器。Java内存模型(JMM)则用于规定多线程环境下的内存访问和操作顺序。 GC是垃圾收集器自动完成的过程,用于回收不再使用的对象,释放内存空间。JVM会根据系统环境和内存需求来决定何时进行GC。我们也可以通过调用System.gc()方法手动触发一次垃圾回收,但是具体的回收时机由JVM决定。需要注意的是,手动调用System.gc()方法并不推荐,因为它会消耗较多的资源。 垃圾收集器是实现垃圾回收的具体实现。它们采用不同的算法和策略来收集和回收垃圾对象。Java中有多种垃圾收集器可供选择,如Serial、Parallel、CMS(Concurrent Mark Sweep)和G1(Garbage-First)等。每个垃圾收集器都有不同的特点和适用场景,可以根据应用程序的需求进行选择和配置。 因此,JVM内存模型定义了对象的分配和回收方式,而垃圾回收器则是具体实现了垃圾回收的过程,根据不同的算法和策略来回收不再使用的对象。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [JVM内存模型垃圾回收](https://blog.csdn.net/weixin_40980639/article/details/125934179)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值