我的编程空间,编程开发者的网络收藏夹
学习永远不晚

简单谈谈Java中的栈和堆

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

简单谈谈Java中的栈和堆

人们常说堆栈堆栈,堆和栈是内存中两处不一样的地方,什么样的数据存在栈,又是什么样的数据存在堆中?

这里浅谈Java中的栈和堆

首先,将结论写在前面,后面再用例子加以验证。

Java的栈中存储以下类型数据,栈对应的英文单词是Stack

基本类型

引用类型变量

方法

栈的优势是,存取速度比堆要快,仅次于寄存器,栈数据可以共享。但缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。

栈中主要存放一些基本类型的变量(int, short, long, byte, float, double, boolean, char)和对象句柄。

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

Java的堆中存储以下类型数据,堆对应的英文单词是Heap

实例对象

在函数中定义的一些基本类型的变量(8种)和对象的引用变量都是在函数的栈Stack内存中分配。当在一段代码块中定义一个变量时,java就在栈中为这个变量分配内存空间,当超过变量的作用域后,java会自动释放掉为该变量分配的内存空间,该内存空间可以立刻被另作他用。

堆Heap内存用于存放由new创建的对象和数组。在堆中分配的内存,由java虚拟机自动垃圾回收器来管理。在堆中产生了一个数组或者对象后,还可以在栈中定义一个特殊的变量,这个变量的取值等于数组或者对象在堆内存中的首地址,在栈中的这个特殊的变量就变成了数组或者对象的引用变量,以后就可以在程序中使用栈内存中的引用变量来访问堆中的数组或者对象,引用变量相当于为数组或者对象起的一个别名,或者代号。

引用变量是普通变量,定义时在栈中分配内存,引用变量在程序运行到作用域外释放。而数组&对象本身在堆中分配,即使程序运行到使用new产生数组和对象的语句所在地代码块之外,数组和对象本身占用的堆内存也不会被释放,数组和对象在没有引用变量指向它的时候,才变成垃圾,不能再被使用,但是仍然占着内存,在随后的一个不确定的时间被垃圾回收器释放掉。这个也是java比较占内存的主要原因,实际上,栈中的变量指向堆内存中的变量,这就是 Java 中的指针!


class Person {
 
    int age;
 
}
 
 
public class LearnHeap {
 
 
    public static void main(String args[]){
 
        int a=10;
        Person person = new Person();
        person.age =20;
 
        change(a,person);
        System.out.println("a="+ a+",and person.age = "+person.age);
 
    }
 
    static void change(int a1, Person person){
 
        a1 = 11;
        person.age= 21;
        System.out.println("a1="+ a1+",and age1 = "+person);
 
    }
 
}

两次的输出结果是什么?猜测下。

以上程序内存加载的执行步骤:

第1步 —— main()函数是程序入口,JVM先执行,首先将main方法压入栈中,在栈内存中开辟一个空间,存放int类型变量a,同时附值10。
在堆中分配一片区域,用来存放和创建Person对象,这片内存区域会有属于自己的内存地址,假设是1001,然后给成员变量赋值,age=20
执行结束后,构造防范弾栈,Person创建完成,将Person的内存地址1001赋值给person(此处person小写,是引用变量类型)

第2步 —— JVM执行change()函数,在栈内存中又开辟一个新的空间,存放int类型变量a和对象Person中person
此时main空间与change空间并存,同时运行,互不影响。

第3步 —— change()方法执行,将a赋值为11,person对象的堆中年龄age赋值为21

第4步 —— change()执行完毕,变量a立即释放,空间消失。但是main()函数空间仍存在,main中的变量a仍然存在,不受影响。而person在堆中对应的地址,所指的age已经赋值=21

实际输出如下:

结论:

如果a()方法中的基本类型(8个)变量x传入b()方法中,并在b()中进行了修改,则a()方法中的x的值保持不变

如果a()方法中的引用类型 变量x传入b()方法中,并在b()中进行了修改,则a()方法中的x的值与b()保持一致

下面对8中基本类型进行简单的测试


package heapandStack;
 
public class LearnHeap02 {
 
    public static void main(String args[]){
 
 
        byte b=10;
        short s=20;
        int i=30;
        long l =40l;
 
        float f =12.34f;
        double d = 100.123d;
 
        char c = 'A';
        boolean flag = true;
 
        change(b,s,i,l,f,d,c,flag);
 
        System.out.println(b);
        System.out.println(s);
        System.out.println(i);
        System.out.println(l);
 
 
        System.out.println(f);
        System.out.println(d);
        System.out.println(c);
        System.out.println(flag);
 
    }
 
    static void change(byte a, short b, int c,long d, float f, double g, char h,boolean x){
 
        a =11;
        b=21;
        c =31;
        d =41l;
        f=12.99f;
        g= 200.123d;
        h ='V';
        x =false;
 
        System.out.println(a);
        System.out.println(b);
        System.out.println(c);
        System.out.println(d);
 
 
        System.out.println(f);
        System.out.println(g);
        System.out.println(h);
        System.out.println(x);
 
    }
}

下面测试一下数组,是不是属于实例对象类型


public class LearnHeap03 {
 
    public static void main(String args[]){
 
     int a[] ={1,2,3};
     change(a);
        for(int i:a)
            System.out.print(i+" ");
 
    }
 
    static void change(int[] a){
        a[0]=4;
        a[1]=5;
        for(int i:a)
            System.out.print(i+" ");
        System.out.println("============ ");
 
    }
}

从结果看出,数组的值被改变了

Java种8种基本数据类型,并不包含String,String的值会被change函数改变吗?String应该存在栈中,还是堆中呢?

先直接上测试代码


public class Learn04 {
 
    public static void main(String args[]){
 
        String s1 = new String("abcd");
        String s2 = "asdfghjkl";
        System.out.println(s1+", "+s2);
        change(s1,s2);
        System.out.println(s1+", "+s2);
 
    }
 
    static void change(String s1,String s2){
        s1 ="123456";
        s2 ="000000";
        System.out.println(s1+", "+s2);
 
    }
}

两种的形式来创建String,第一种是用new()来新建对象的,它会在存放于堆中。每调用一次就会创建一个新的对象。 而第二种是先在栈中创建一个对String类的对象引用变量s2,然后查找栈中有没有存放"asdfghjkl",如果没有,则将"asdfghjkl"存放进栈,并令str指 向”abc”,如果已经有”asdfghjkl” 则直接令s2指向“asdfghjkl”。 

 

既然讲到两种形式创建String,下面讲一个String两种形式创建的区别,先看一段代码


public class Learn05 {
 
    public static void main(String args[]){
 
        String s1 = new String("abcd");
        String s2 = "abcd";
        boolean a =s1.equals(s2);
        boolean b =(s1==s2);
 
        System.out.println(a);
        System.out.println(b);
 
        String s3 = "abcd";
        boolean a1 =s3.equals(s2);
        boolean b1 =(s3==s2);
 
        System.out.println(a1);
        System.out.println(b1);
 
 
    }
 
}

总结

到此这篇关于Java中的栈和堆的文章就介绍到这了,更多相关Java中栈和堆内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

简单谈谈Java中的栈和堆

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

浅谈一下Java中的堆和栈

这篇文章主要介绍了一下Java中的堆和栈,Java数据类型在执行过程中存储在两种不同形式的内存中:栈和堆,它们通常由运行Java虚拟机(JVM)的底层平台维护,需要的朋友可以参考下
2023-05-18

详谈java 堆区、方法区和栈区

堆区:只存放类对象,线程共享;方法区:又叫静态存储区,存放class文件和静态数据,线程共享;栈区:存放方法局部变量,基本类型变量区、执行环境上下文、操作指令区,线程不共享;class A { private String a = “aa
2023-05-31

简单谈谈Vue3中的ref和reactive

vue3中实现响应式数据的方法是就是使用ref和reactive,所谓响应式就是界面和数据同步,能实现实时更新,下面这篇文章主要给大家介绍了关于Vue3中ref和reactive的相关资料,需要的朋友可以参考下
2023-05-16

简单谈谈Python中的闭包

Python中的闭包 前几天又有人留言,关于其中一个闭包和re.sub的使用不太清楚。我在编程网搜索了下,发现没有写过闭包相关的东西,所以决定总结一下,完善Python的内容。 1. 闭包的概念 首先还得从基本概念说起,什么是闭包呢?来看下
2022-06-04

简单谈谈python中的多进程

进程是由系统自己管理的。 1:最基本的写法from multiprocessing import Pooldef f(x):return x*xif __name__ == '__main__':p = Pool(5)print(p.map
2022-06-04

简单谈谈Python中的元祖(Tuple)和字典(Dict)

前言 本文记录了对于Python的数据类型中元祖(Tuple)和字典(Dict)的一些认识,以及部分内置方法的介绍。下面话不多说,来看看详细的介绍吧。 元祖 Tuple 特点:元祖内的数据不可变 一个元素的定义:T = (1,)>>> T=
2022-06-04

简单谈谈Android中SP与DP的区别

从一开始写Android程序,就被告知这些常识 一、dp(或者dip device independent pixels) 一种基于屏幕密度的抽象单位。在每英寸160点的显示器上,1dp=1px。不同设备有不同的显示效果,这个和设备硬件有关
2022-06-06

简单谈谈python中的Queue与多进程

最近接触一个项目,要在多个虚拟机中运行任务,参考别人之前项目的代码,采用了多进程来处理,于是上网查了查python中的多进程 一、先说说Queue(队列对象) Queue是python中的标准库,可以直接import 引用,之前学习的时候有
2022-06-04

简单谈谈Python中函数的可变参数

前言在Python中定义函数,可以用必选参数、默认参数、可变参数和关键字参数,这4种参数都可以一起使用,或者只用其中某些,但是请注意,参数定义的顺序必须是:必选参数、默认参数、可变参数和关键字参数。 可变参数( * ) 可变参数,顾名思义,
2022-06-04

简单谈谈Angular中的独立组件的使用

这篇文章主要介绍了简单谈谈Angular中的独立组件的使用的相关资料,通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,需要的朋友可以参考下
2022-11-13

简单谈谈Python中的反转字符串问题

按单词反转字符串是一道很常见的面试题。在Python中实现起来非常简单。def reverse_string_by_word(s):lst = s.split() # split by blank space by defaultretur
2022-06-04

浅谈Java数组的一些使用方法及堆栈存储

数组用于存储一组同一数据类型数据的容器数组会对放入其中的数据自动编号,编号是从0开始的---下标定义格式数据类型[] 数组名 = new 数据类型[数组的大小];---可以先声明再初始化int[] arr = new int[5];---定
2023-05-31

简单谈谈Python中的几种常见的数据类型

计算机顾名思义就是可以做数学计算的机器,因此,计算机程序理所当然地可以处理各种数值。但是,计算机能处理的远不止数值,还可以处理文本、图形、音频、视频、网页等各种各样的数据,不同的数据,需要定义不同的数据类型。在Python中,能够直接处理的
2022-06-04

java中栈和堆的区别

在说堆和栈之前,我们先说一下JVM(虚拟机)内存的划分: (推荐学习:java课程)Java程序在运行时都要开辟空间,任何软件在运行时都要在内存中开辟空间,Java虚拟机运行时也是要开辟空间的。JVM运行时在内存中开辟一片内存区域,启动时在自己的内
java中栈和堆的区别
2021-03-03

简单谈谈Java遍历树深度优先和广度优先的操作方式

这篇文章主要介绍了简单谈谈Java遍历树深度优先和广度优先的操作方式的相关资料,需要的朋友可以参考下
2023-03-24

详细谈谈Java中long和double的原子性

目录前言JVM中对long的操作是不是原子操作?为什么对long的操作不是原子的?在硬件,操作系统,JVM都是64位的情况下呢?总结前言java中基本类型中,long和double的长度都是8个字节,32位(4字节)处理器对其读写操作无法一次完成,那么,JVM
2018-10-04

Java中的栈和堆有什么用

在Java中,栈和堆都是用于内存管理的。1. 栈(Stack):栈是一种后进先出(LIFO)的数据结构,用于存储方法调用和局部变量。每个线程在运行时都会有一个独立的栈空间,用于保存方法调用时的参数、局部变量和返回地址等信息。当一个方法被调用
2023-08-16

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录