• JVM内存模型篇【JVM内存模型】


    1、JVM内存模型

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    本地方法区

    Java官方对于本地方法的定义为methods written in a language other than the Java programming language,就是使用非Java语言实现的方法,但是通常我们指的一般为C或者C++,因此这个栈也有着C栈这一称号。一个不支持本地方法执行的JVM没有必要实现这个数据区域。本地方法栈基本和JVM栈一样,其大小也是可以设置为固定值或者动态增加,因此也会对应抛出StackOverflowError和OutOfMemoryError错误。

    方法区

    1、方法区中保存着,类、静态变量、静态方法、常量、普通方法

    2、方法区是线程共享的;当有多个线程都用到一个类的时候,而这个类还未被加载,则应该只有一个线程去加载类,让其他线程等待;

    3、方法区的大小不必是固定的,jvm可以根据应用的需要动态调整。jvm也可以允许用户和程序指定方法区的初始大小,最小和最大限制;

    4、方法区同样存在垃圾收集,因为通过用户定义的类加载器可以动态扩展Java程序,这样可能会导致一些类,不再被使用,变为垃圾。这时候需要进行垃圾清理。

    栈内存

    栈内存:栈内存首先是一片内存区域,存储的都是局部变量,凡是定义在方法中的都是局部变量(方法外的是全局变量),for循环内部定义的也是局部变量,是先加载函数才能进行局部变量的定义,所以方法先进栈,然后再定义变量,变量有自己的作用域,一旦离开作用域,变量就会被释放。栈内存的更新速度很快,因为局部变量的生命周期都很短。栈的读取速度比堆快,但栈上存储的数据受到有效范围的限制。Java的栈也受到同样的限制,当一次方法调用结束,该方法存储在栈上的数据将清空。在 Java中,所有的(普通)对象都储存在堆上。因此,new关键字的完整含义是,在堆上创建对象。
    基本类型(primitive type)的对象,比如int, double,保存在栈上。当我们声明基本类型时,不需要new。一旦声明,Java将在栈上直接存储基本类型的数据。所以,基本类型的变量名表示的是数据本身,不是引用。

    堆内存
    对象的引用存储在栈区,但是对象实体存放在堆内存中
    在这里插入图片描述
    在这里插入图片描述

    堆内存:存储的是数组和对象(其实数组就是对象),凡是new建立的都是在堆中(这句话还是不严谨,JVM中的逃逸分析就打破了这一点,堆中存放的都是实体(对象),实体用于封装数据,而且是封装多个(实体的多个属性),如果一个数据消失,这个实体也没有消失,还可以用,所以堆是不会随时释放的,但是栈不一样,栈里存放的都是单个变量,变量被释放了,那就没有了。堆里的实体虽然不会被释放,但是会被当成垃圾,Java有垃圾回收机制不定时的收取。

    当一个实体,没有引用数据类型指向的时候,它在堆内存中不会被释放,而被当做一个垃圾,在不定时的时间内自动回收,因为Java有一个自动回收机制,(而c++没有,需要程序员手动回收,如果不回收就越堆越多,直到撑满内存溢出,所以Java在内存管理上优于c++)。自动回收机制(程序)自动监测堆里是否有垃圾,如果有,就会自动的做垃圾回收的动作,但是什么时候收不一定。

    堆是线程共享的内存区域,栈是线程独享的内存区域。
    本地线程分配缓冲(Thread Local Allocation Buffer,TLAB)(TLAB的出现,使得每个线程初始化时,都会从内存中分配一块专属于自己的内存(大小为100K),别的线程可以读取该内存的变量,但不能写入该内存)为了防止两个线程往一块内存中分配对象。
    在这里插入图片描述

  • 相关阅读:
    ECMAScript13 中11个令人惊叹的 JavaScript 新特性
    Nginx学习笔记07——Nginx负载均衡
    RK3399驱动开发 | 04 - WK2124串口芯片驱动浅析
    CentOS7系统及内核升级
    C数据结构:树和森林存储方式与遍历方式
    谷歌翻译器-谷歌翻译器软件批量自动翻译
    JAVA学习------通配符参数
    redis实战-redis实现好友关注&消息推送
    Windows Server FTP文件服务器安装和配置
    抽象类和接口
  • 原文地址:https://blog.csdn.net/m0_67390788/article/details/126743782