[java]java的堆内存和栈内存解析--举例进行内存分析(代码片段)

zsytony zsytony     2022-11-30     308

关键词:

[Java]Java的堆内存和栈内存解析–举例进行内存分析

明确概念

从堆和栈的功能和作用来通俗的比较,堆主要用来存放对象的,栈主要是用来执行程序的。

堆内存(Heap)

  • 通常是成员分配和释放的,C/C++是由程序员进行释放或者程序结束时回收,Java中由垃圾清理机制进行释放和回收。
  • new出来的对象和数组是放在堆内存中。堆内存是运行时的数据区,垃圾收集器会自动进行回收,但因为是运行时动态分配的内存,存取速度较慢。
  • 垃圾回收机制是通过判断堆内存中某块被分配的空间的引用数实现的,即存在一个引用计数器,任何引用计数为0的对象会被作为垃圾被收集。

栈内存(Stack)

  • 基本类型的变量和对象的引用变量在栈内存中分配.
  • 当超过变量作用域后,java会自动释放掉为该变量分配的空间。

两者联系

栈内存中的变量指向堆内存中的变量,相当于java中的“指针”

实例说明

代码

//
class BirthDate 
    private int day;
    private int month;
    private int year;

    public BirthDate(int d, int m, int y) 
        day = d; 
        month = m; 
        year = y;
    

    public void setDay(int d) 
        day = d;
    

    public void setMonth(int m) 
        month = m;
    

    public void setYear(int y) 
        year = y;
    

    public int getDay() 
        return day;
    

    public int getMonth() 
        return month;
    

    public int getYear() 
        return year;
    

    public void display() 
        System.out.println
        (day + " - " + month + " - " + year);
    



public class Test
    public static void main(String args[])
        Test test = new Test();
        int date = 9;
        BirthDate d1= new BirthDate(7,7,1970);
        BirthDate d2= new BirthDate(1,1,2000);    
        test.change1(date);
        test.change2(d1);
        test.change3(d2);
        System.out.println("date=" + date);
        d1.display();
        d2.display();
    

    public void change1(int i)
        i = 1234;
    

    public void change2(BirthDate b) 
        b = new BirthDate(22,2,2004);
    

    public void change3(BirthDate b) 
        b.setDay(22);
    

流程分析

  1. 从main开始分析
    • 在栈内存中生成了一个test变量,指向堆内存中new出来的Test对象
  2. int date = 9
    在栈内存中生成了一个变量date:9
  3. BirthDate d1= new BirthDate(7,7,1970);
    • 在栈内存中生成了一个d1变量,指向堆内存中new出来的BirthDate对象
    • new出来的BirthDate对象包含三个变量 年月日
    • 栈内存中生成三个临时变量年月日,赋值给堆内存中的BirthDate对象的三个成员变量
      至此 图如下
    • 赋值完成后,三个临时变量的生命周期结束,在栈内存中被释放。
  4. d2的生成过程如d1,不再赘述
  5. test.change1(date);
    • 调用change1函数时,会在栈内存中生成变量 i ,i=date ,值传递i=9,执行函数时,i=1234,函数执行完成后,局部变量消失,i被释放掉,内存中状态不发生变化


  6. test.change2(d1);
    • 调用change2时,在栈内存中生成b变量,传递参数时,b指向的d1所指向的对象
    • 执行函数时,与第3部相同的,b指向了在堆内存中生成了一个BirthDate对象
    • 指向完毕后,b变量消失,堆内存中只剩下一个BirthDate对象,此时该对象的引用计数为0,java的垃圾回收机制会自动将其内存回收。

      7.test.change3(d2);
    • 类似于6,临时变量b先指向了d2指向的对象,指向方法时,调用b.setDay(22),在栈内存中生成临时变量d = 22,将其赋值给堆内存中d2指向的对象的day变量。执行完成后,b和d变量消失,堆内存中对象的日期被更新

内存分配策略

程序运行时,内存分配有三种策略

  • 静态分配
  • 栈式分配
  • 堆式分配

静态内存分配

编译时确定每个数据目标的存储需求,分配固定的内存空间,故要求程序代码中不能有可变数据结构,也不能有嵌套和递归。

栈式内存分配

也称为动态内存分配,由一个类似于堆栈的运行栈实现,程序对数据去的需求在编译时不知道的,只用运行时才能知道。但是一般规定,运行时,进入一个程序模块之前,必须知道该程序模块数据去大小才能分配内存,按照先进后出的原则分配。
通俗的说就是,要求在运行时程序模块的入口处必须知道所有的存储要求。

堆式内存分配

专门负责编译时或运行时模块入口都无法确定存储需求的数据结构的内存分配,如可变长数据结构和对象实例,有大片可利用的块或者空闲块组成,可以按照任意顺序分配和释放。

参考资料:

http://www.cnblogs.com/laoyangHJ/articles/java_gc.html
http://www.java800.com/jc-59050343.html
http://www.cnblogs.com/whgw/archive/2011/09/29/2194997.html

java的堆和栈

  在说堆和栈之前,我们先说一下JVM(虚拟机)内存的划分:     Java程序在运行时都要开辟空间,任何软件在运行时都要在内存中开辟空间,Java虚拟机运行时也是要开辟空间的。JVM运行时在内存中开辟一片... 查看详情

java中的堆内存和栈内存(代码片段)

在Java中,堆内存和栈内存是两种不同的内存分配方式。堆内存堆内存用于存放由new创建的对象和数组。堆内存的分配由Java虚拟机的自动垃圾回收器来管理,因此程序员可以专注于业务逻辑的实现,无需关注内存回收的细节。Java... 查看详情

java中的堆内存与栈内存,你get到了吗?

Java中的堆和栈学Java的朋友应该都知道,在Java中把「内存」划分成两种:一种是「栈内存」,一种是「堆内存」。我们平时在函数中定义的一些「基本类型的变量」和「对象的引用变量」都是在函数的「栈内存」中分配的。当我... 查看详情

java中的堆和栈的区别

当一个人开始学习Java或者其他编程语言的时候,会接触到堆和栈,由于一开始没有明确清晰的说明解释,很多人会产生很多疑问,什么是堆,什么是栈,堆和栈有什么区别?更糟糕的是,Java中存在栈这样一个后进先出(LastInFirs... 查看详情

java中的堆和栈的区别

当一个人开始学习Java或者其他编程语言的时候,会接触到堆和栈,由于一开始没有明确清晰的说明解释,很多人会产生很多疑问,什么是堆,什么是栈,堆和栈有什么区别?更糟糕的是,Java中存在栈这样一个后进先出(LastInFirs... 查看详情

值类型和引用类型的区别i数据结构中的堆和栈和内存中的堆和栈的区别(代码片段)

值类型和引用类型的区别I数据结构中的堆和栈和内存中的堆和栈的区别一、值类型和引用类型二、值类型和引用类型的区别三、数据结构中的堆和栈和内存中的堆和栈的区别(一)数据结构中的堆和栈1.栈:装数据的... 查看详情

jvm中堆和栈的区别

...JVM虚拟机内部,我们这里介绍的自然是JVM(虚拟)内存中的堆和栈。 区别java中堆和栈的区别自然是面试中的常见问题,下面几点就是其具体的区别 各司其职最主要的区别就是栈内存用来存储局部变量和方法调用。而堆... 查看详情

数据结构中的堆和栈与内存分配中的堆区和栈区分析

比較全面的总结了诸多版本号,知识无国界。感谢各位的辛勤劳作。在计算机领域,堆栈是一个不容忽视的概念,我们编写的C/C++语言程序基本上都要用到。但对于非常多的初学着来说,堆栈是一个非常模糊的概念。(1)&... 查看详情

jvm的堆内存和栈内存中存储的数值或类型的区别在哪里

基本类型变量的值和内容是一致的引用类型变量的值在堆内存,赋值的内容是一个地址,这个地址也在栈内存,指向堆内存引用类型变量的值是内存地址,内存地址在栈内存,指向堆;内容是实例,在堆内存引用类型变量时,栈内存存... 查看详情

javascript中的堆和栈

栈(stack)栈stack为自动分配的内存空间,它由系统自动释放;堆(heap)堆heap是动态分配的内存,大小不定也不会自动释放;JavaScript的数据类型分为两种,基本类型和引用类型1.基本类型 Undefined、Null、Boolean、Number和 Stri... 查看详情

java堆栈内存分配

...和栈内存的教程以及参考说明,但是很难解释什么是程序的堆内存以及栈内存一:Java堆内存空间Java程序运行时使用javaHeap内存为对象以及JRE类分配内存,不论我们在何时创建何种类型的对象,他总是在堆内存中创建的Java垃圾收... 查看详情

关于内存中栈和堆的区别(非数据结构中的堆和栈,区别)

本文转载自:http://blog.csdn.net/fenghuayoushi/article/details/6074666----------------------------------------------------------------------------------------------------------------------- 下面内容转自:http 查看详情

关于内存中栈和堆的区别(非数据结构中的堆和栈,区别)

本文转载自:http://blog.csdn.net/fenghuayoushi/article/details/6074666 ----------------------------------------------------------------------------------------------------------------------- 下面内容转 查看详情

基础才是重中之重~内存里的堆和栈(代码片段)

内存分成5个区,他们分别是堆、栈、自由存储区、全局/静态存储区和常量存储区。栈  先进后出(FILO—First-In/Last-Out)就是那些由编译器在需要的时候分配,在不需要的时候自动清楚的变量的存储区。里面的变量通常是局部... 查看详情

js中的堆和栈(代码片段)

一.栈和堆栈(stack):栈会自动分配内存空间,会自动释放,存放基本类型,简单的数据段,占据固定大小的空间。(基本类型:String,Number,Boolean,Null,Undefined)堆(heap):动态分配的内存,大小不定也不会自动释放,存放引用... 查看详情

java堆和栈的介绍和区别

  Java的堆(heap)是一个运行时数据区,类的(对象从中分配空间。这些对象通过new、newarray、anewarray和multianewarray等指令建立,它们不需要程序代码来显式的释放。堆是由垃圾回收来负责的,堆的优势是可以动态地分配内存大... 查看详情

初识栈内存和堆内存

Java中的堆和栈   Java把内存划分成两种:一种是栈内存,一种是堆内存。   在函数中定义的一些基本类型的变量和对象的引用变量都在函数的栈内存中分配。   当在一段代码块定义一个变量时,Java就在栈中为... 查看详情

java中堆内存和栈内存详解

...对象的语句所在地代码块之外,数组和对象本身占用的堆内存也不会被释放,数组和对象在没有引用变量指向它的时候, 查看详情