当前位置: 首页 > article >正文

【JVM】运行时数据区

        按照不同的数据分区进行存储(方法区、堆、栈、本地方法栈、程序计数器)。

程序计数器

        作用:用来记录程序执行的指令的位置。

        特点:内存空间小,运行速度快,是线程私有的(每个线程都有一个计数器),生命周期与线程同步,不会出现内存溢出,没有垃圾回收。

虚拟机栈

        栈是运行单位,管理方法(Java自己写的方法)的运行调用方法入栈,执行结束出栈(口语描述:一个方法对应一个栈帧,如果方法A中调用了方法B,那么方法B入栈,成为当前栈帧,也就是处于运行状态,运行结束后出栈,方法A成为当前栈帧)。栈是线程私有的。没有垃圾回收,存在内存溢出的可能。

        栈溢出错误:

package javaException;

public class Demo {

    /*
        常见的异常:
            Error
                java.lang.OutOfMemoryError 内存溢出错误,程序无法解决
                java.lang..StackOverflowError 栈溢出错误,程序无法解决
    */

    public static void main(String[] args) {

        System.out.println(sum(1000000)); // java.lang..StackOverflowError

    }

    public static int sum(int n ) {
        if (n == 1) {
            return 1;
        }
        return n + sum(n - 1);
    }

}

栈帧的构成

每个栈帧中存储着:

        局部变量表(Local Variables)

        局部变量表是一组变量值存储空间,用于存放方法参数和方法内部定义的局部变量。对于基本数据类型的变量,则直接存储它的值,对于引用类型的变量,则存的是指向对象的引用。

        操作数栈(Operand Stack)(或表达式栈)

        栈最典型的一个应用就是用来对表达式求值。在一个线程执行方法的过程中,实际上就是不断执行语句的过程,而归根到底就是进行计算的过程。因此可以这么说,程序中的所有计算过程都是在借助于操作数栈来完成的。

        方法返回地址(Retuen Address)(或方法正常退出或者异常退出的定义)

        当一个方法执行完毕之后,要返回之前调用它的地方,因此在栈帧中必须保存一个方法返回地址。

    public void test() {
        int a = 10;
        int b = 5; // 局部变量表
        int c = a++ + b; // 运算 操作数栈
        //记录被调用方法的位置
    }

本地方法栈

        管理运行本地方法的地方。

本地方法

        native 关键字修饰的方法,没有方法体,它是C语言写的、系统库中提供的方法。例如 Object 中的 hashCode()、getClass()、clone()、notify()、notifyAll()、wait(long timeout);Java语言是没有权力直接操作硬盘的,必须要经过操作系统,比如 FileInputStream 里面的 read0() 就是一个本地方法;Thread 中的 start0()等等······

        是线程私有的。没有垃圾回收,存在内存溢出的可能

        存放程序中产生的对象。是运行时数据区最大的一块空间,大小可以调节。线程是共享的。存在内存溢出的可能,会进行垃圾回收,并且是垃圾收集器重点回收区域。

堆空间分区

新生代:

        伊甸园区:存放刚创建的对象。

        幸存者1区:存放伊甸园区和另一个幸存者区经过垃圾回收后存活下来的对象。

        幸存者2区:两个幸存者区可以交替使用,始终有一个区域是空闲的。

老年代:

        存放生命周期长的/非常大的对象。经历过15次垃圾回收后依然存活的对象,就会被存放在老年代。

为什么要分区(代)?

        将对象根据存活概率进行分类,对存活时间长的对象,放到固定区,从而减少扫描垃圾时间及 GC 频率。针对分类进行不同的垃圾回收算法,对算法扬长避短。

对象创建以及在内存分布过程

        1.新创建的对象存放到伊甸园区。

        2.垃圾回收时,将伊甸园区存活的对象移入到幸存者0区。

        3.程序继续运行,再次创建的对象还是保存到伊甸园区。

        4.下一次垃圾回收到来时,将伊甸园区和幸存者0区存活的对象移入到幸存者1区,交替反复执行。

        5.当一个对象经历过15次垃圾回收后仍然存活,那么就将此对象移入到老年代。在对象头中有4个 byte 位用来记录回收次数。回收次数可以设置,但是最大值是15。

        Minor GC:是针对新生代进行的垃圾回收。频繁回收新生代。

        Major GC:是针对老年区进行的垃圾回收。较少回收老年代。

        FULL GC:整堆收集,实际开发中要尽量避免整堆收集。什么时候会触发整堆收集,这个我们后面再说。

空间比例

        老年代和老年代比例 2 : 1

        伊甸园区和两个幸存者区比例 8 : 1 : 1

堆空间的参数设置

        JVM调优就是根据程序实际运行的需要设置参数,调整各个区间比例大小。

        官网地址:https://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html

        -XX:+PrintFlagsInitial 查看所有参数的默认初始值
        -Xms:初始堆空间内存
        -Xmx:最大堆空间内存
        -Xmn:设置新生代的大小
        -XX:MaxTenuringTreshold:设置新生代垃圾的最大年龄
        -XX:+PrintGCDetails 输出详细的 GC 处理日志

        加入参数,Apply,然后ok:

        运行,就能查看所有参数的默认初始值:

        上面的演示示例只是在临时运行某个文件的时候可以调一调,看一看。正常情况肯定是在 JVM 的配置文件里面修改。

方法区

        主要存储加载到虚拟机的类信息,大小可以调节,是线程共享的,存在内存溢出的可能。

方法区大小设置

        Java 方法区的大小不必是固定的,JVM 可以根据应用的需要动态调整。

         元数据区大小可以使用参数 -XX:MetaspaceSize 指定。

        方法区一旦沾满 就会触发 Full GC,因此为了减少 FullGC,可以给 -XX:MetaspaceSize 设置一个较高的值。

方法区的垃圾回收

        方法区是存在垃圾回收的,只不过条件比较苛刻,一般情况下也可以认为类是不会被卸载的,需要同时满足3个条件,类才可以被卸载:

        1.该类的所有对象以及子类对象都不存在。

        2.加载该类的类加载器不存在了。

        3.该类的 Class 对象没有被其他地方引用。

        

        


http://www.kler.cn/news/314625.html

相关文章:

  • Ubuntu 20.04 内核升级后网络丢失问题的解决过程
  • 《DevOps实践指南》笔记-Part 3
  • Swift里的数值变量的最大值和最小值
  • 分布式光伏发电站数据采集设备管理硬件解决方案
  • 机器学习——Stacking
  • C++速通LeetCode中等第21题-排序链表(空间O(1))
  • 828华为云征文 | 华为云X实例的镜像管理详解
  • Unexpected end of file from server 错误
  • 系统架构设计师教程 第5章 5.4 软件测试 笔记
  • 论文阅读笔记:Sapiens: Foundation for Human Vision Models
  • MoCo和SimCLR【CV双雄】
  • mxnet算子调用kernel示例(MINIST)
  • Java面试篇-AOP专题(什么是AOP、AOP的几个核心概念、AOP的常用场景、使用AOP记录操作日志、Spring中的事务是如何实现的)
  • SYN Flood攻击原理,SYN Cookie算法
  • 【数据结构C语言】【入门】【首次万字详细解析】入门阶段数据结构可能用到的C语言知识,一章让你看懂数据结构!!!!!!!
  • 我的AI工具箱Tauri版-FasterWhisper音频转文本
  • 什么是 HTTP/3?下一代 Web 协议
  • 直播音频解决方案
  • PyTorch 实现手写数字识别
  • 2024华为杯数模CDEF成品文章!【配套完整解题代码+数据处理】
  • 一文读懂 JS 中的 Map 结构
  • 图形化编程012(变量-倒计时)
  • 【JVM原理】运行时数据区(内存结构)
  • 前端框架的比较与选择详解
  • 数据库提权【笔记总结】
  • 计算机毕业设计 社区医疗服务系统的设计与实现 Java实战项目 附源码+文档+视频讲解
  • web基础—dvwa靶场(四)​File Inclusion
  • 电脑文件防泄密软件哪个好?这六款软件建议收藏【精选推荐】
  • MQ(RabbitMQ)笔记
  • Flutter 约束布局