JAVA基础知识|堆和栈

Posted maikucha

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JAVA基础知识|堆和栈相关的知识,希望对你有一定的参考价值。

一、java六个存储数据的地方

1)寄存器(register):这是最快的存储区,因为它位于不同于其他存储区的地方——处理器内部。但是寄存器的数量极其有限,所以寄存器由编译器根据需求进行分配。你不能直接控制,也不能在程序中感觉到寄存器存在的任何迹象。

2)栈(stack):位于通用RAM中,这是一种快速有效的分配存储方法,仅次于寄存器。用于存放基本数据类型的变量和对象、数组的引用。

3)堆(heap):也位于通用RAM中,用于存放new出来的对象,用堆进行存储比用栈进行存储需要更多的时间。

4)静态存储(static storage):这里的“静态”是指“在固定的位置”。静态存储里存放程序运行时一直存在的数据,即关键字static标识的属性,但JAVA对象不会存放在静态存储空间里。

*为什么非静态方法,不可以使用静态属性?

因为静态方法和静态属性的编译要在非静态方法之后,当非静态方法编译使用的时候,静态属性还没生成,会导致报错!

5)常量存储(constant storage):常量值通常直接存放在程序代码内部,这样做是安全的,因为它们永远不会被改变。有时在嵌入式系统中,常量本身会和其他部分分割离开,所以在这种情况下,可以选择将其放在ROM中。所以常量存储用于存放final关键字修饰的字符串常量和基本类型常量。

6)非RAM存储:如果数据完全存活于程序之外,那么它可以不受程序的任何控制,在程序没有运行时也可以存在。

二、堆和栈

相同点:都用于存储数据

不同点:  

  1)栈用于存放基本数据类型的变量和对象、数组的引用,堆用于存放new出来的对象

  2)栈中存放的数据,大小和生存期必须确定,灵活性不足。堆中存放的数据,不必知道数据大小,也不必知道生命周期,灵活性较高,导致速度较慢

  3)生命周期

     当一个方法执行时,每个方法都会建立自己的内存栈,在这个方法中定义的变量将会放到这块栈内存里,随着方法的结束而销毁(不需要使用GC)。

       当执行new对象的时候,数据才会在堆中生成,只有当一个对象没有任何引用变量去引用它时,系统的垃圾回收器(GC)才会在合适的时候回收它。

  4)栈解决程序的运行问题,即程序如何执行,或者说如何处理数据;堆解决的是数据存储的问题,即数据怎么放、放在哪儿。

技术分享图片
/**
 * 汽车类
 */
public class Car {

    //编号
    private int id;
    //车名
    private String name;
    //车速
    private double speed;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public double getSpeed() {
        return speed;
    }

    public void setSpeed(double speed) {
        this.speed = speed;
    }

    public Car(int id, String name, double speed) {
        this.id = id;
        this.name = name;
        this.speed = speed;
    }

    public Car() {
    }

    @Override
    public String toString() {
        return "Car{" +
                "id=" + id +
                ", name=‘" + name + ‘\\‘‘ +
                ", speed=" + speed +
                ‘}‘;
    }
}
View Code
技术分享图片
        int i = 1;
        Car car = new Car(1, "bmw", 200);
View Code

 图形化分析:

技术分享图片

继续看下面代码,并思考输出值

技术分享图片
        int i = 1;
        Car car = new Car(1, "bmw", 200);
        Car newCar = car;
        newCar.setSpeed(300);
        System.out.println(car.toString());
        System.out.println(newCar.toString());
View Code

图形化分析:

技术分享图片

代码中Car newCar = car;只是将引用的地址给了newCar,他们指向堆中同一个对象,所以当newCar对对象做出改变的时候,car所指向的对象也同样发生了变化。

有时候在代码中,我们不希望两个变量指向同一个对象,可以使用clone的方式,重新在堆中生成一个相同的对象。

以上是关于JAVA基础知识|堆和栈的主要内容,如果未能解决你的问题,请参考以下文章

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

java中的堆和栈

java堆和栈的理解

Java 中的堆和栈

堆和栈

java中堆和栈的区别!!!!