• Java 中的 JVM、堆和栈 -- 初步了解


    JVM -- Java Virtual Machine(Java虚拟机)

      —— 因为要说堆和栈,所以我们必须要先简单的说一下JVM。(JVM详细请找度娘啦~)

      首先,我们都知道 java 一直宣传的口号是:一次编译,到处运行。其实它具体的实现是因为 java 程序经过一次编译之后,将 java 代码编译为字节码也就是 class 文件,然后只要在不同平台上安装对应的JVM,就可以运行字节码文件,运行我们编写的Java程序。

      所以说它是 java 的核心和基础。

      个人觉得,它大概的执行过程就是:

        ① 加载 .class 文件(它也只能加载class文件)

        ② 管理并分配内存

        ③ 执行垃圾回收

      (emmm..就到这吧。下面才是重点)

      JVM 的内存分配 -- JVM 的内存划分为五片,分别是:PC寄存器、方法区、堆、Java栈、本地方法栈

      1. 方法区和堆由所有线程共享

      2. Java栈和PC寄存器由线程独享,在新线程的创建的时间里

      3. 本地方法栈:存储本地方法调用的状态

      下面重点说一下,堆和栈。

    堆(Heap)和栈(Stack)

      一个简单总结:

        栈(stack):空间小,速度比较快, 用来放对象的引用,存取速度比堆要快。

        堆(heep): 大,一般所有创建的对象都放在这里。

      

      堆和栈是两种内存分配的两个统称,都是Java用来在Ram中存放数据的地方(java 自动管理栈和堆,程序员不能直接设置)。可能有很多种不同的实现方式,但是实现要符合几个基本的概念:

      1. 栈--后进先出。对栈而言,栈中的新加数据项放在其他数据的顶部,移除时你也只能移除最顶部的数据(不能越位获取)。

      2. 对堆而言,数据项位置没有固定的顺序。你可以以任何顺序插入和删除,因为他们没有“顶部”数据这一概念。

      栈(Stack):栈内存首先是一片内存区域,存储的都是些局部变量(凡是定义在方法中的都是局部变量,方法外的是全局变量)

      注意:for 循环内部定义的也是局部变量,是先加载函数才能进行局部变量的定义,所以方法先进栈,然后再定义变量。

      变量有自己的作用域(也就是由{...}括起来的区域),一旦离开作用域,变量就会被释放(大概是方法执行完成到方法外面的时候,变量销毁的意思)。栈内存更新速度很快,因为局部变量的生命周期都很短。

      栈有一个很重要的特殊性,就是存在栈中的数据可以共享。例:

        我们同时定义:

                int a = 3; 
    int b = 3;
        编译器先处理int a = 3;首先它会在栈中创建一个变量为a 的引用,然后查找有没有字面值为 3 的地址,没找到,就开辟一个存放 3 这个字面值的地址,然后将 a 指向 3 的地址。接着处理int b = 3;在创建完 b 的引用变量后,由于在栈中已经有 3 这个字面值,便将 b 直接指向 3 的地址。
    这样,就出现了 a 与 b 同时均指向 3 的情况。特别注意的是,这种字面值的引用与类对象的引用不同。
     

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

      堆和栈的联系:

       假设我们现在在主函数里面声明一个数组 int arr = new int[3] ,它现在是没有值的,只是有这么一个数组对象创建在堆里面,然后它有了一个内存地址,并且进行了默认的初始化(未初始化的数据是不能用的,所以在栈里面不能用,堆里面能用,就是因为默认初始化过了)。

       然后栈里面存放的只是堆内存地址(对象的引用),而不是这个 arr 数组的这个实体。我们通过栈里面的这个地址指向 arr 数组这个实体,进行操作。

       当 arr 被置为 null ,也就是没有任何指向引用。arr 这时候当做一个垃圾,不定时的时间内自动回收(java 自动回收机制)。

      堆与栈的区别:

        1.栈内存存储的是局部变量而堆内存存储的是实体;

        2.栈内存的更新速度要快于堆内存,因为局部变量的生命周期很短;

        3.栈内存存放的变量生命周期一旦结束就会被释放,而堆内存存放的实体会被垃圾回收机制不定时的回收。

        4.栈是后进先出的,拿的是顶部的数据。而堆没有顶部的概念。

  • 相关阅读:
    线程等待和通知
    什么是代码?code?
    代理(正向代理)和反向代理的区别是什么?
    什么是代理,什么是代理服务器,使用代理服务器的目的是什么?
    计算领域,编码的含义到底是什么?
    linux中,通过crontab -e编辑生成的定时任务,写在哪个文件中
    linux,shell中if else if的写法,if elif
    linux,shell脚本中获取脚本的名字,使用脚本的名字。
    linux,crontab定时任务中为脚本指定使用参数,crontab的脚本中是否可以带参数
    ssh在本地调用远程主机上的命令,不登录远程主机shell
  • 原文地址:https://www.cnblogs.com/sun7897/p/8796614.html
Copyright © 2020-2023  润新知