Java堆栈的理解

作者: dylanhuang88 | 来源:发表于2017-03-18 16:04 被阅读0次

概述

先Copy一个概念:JVM是基于堆栈的虚拟机。JVM为每个新创建的线程都分配一个堆栈.也就是说,对于一个Java程序来说,它的运行就是通过对堆栈的操作来完成的。堆栈以帧为单位保存线程的状态。JVM对堆栈只进行两种操作:以帧为单位的压栈和出栈操作。

例子分析

堆是用来存储new出来的对象,也就是真实对象的存储地方。栈是用来存储基本变量、局部变量及对象的引用的。

举个来说明吧


class User {
    private int id;
    private String name;
    
    public User(int sid, String sname) {
        this.id = sid;
        this.name = sname;
    }
}

public void test() {
    int a = 10;
    int b = 10;
    b  = 12;
    String c = "hello";
    String d = new String("hello");
    User user = new User(10, "hello");
}

基本变量类型都是存储在栈中的,所以int型的a、b、c都存在栈中。具体的操作再来分析下:

int a = 10会检查栈中有没有10这个值,没有就创建了一个10的值,再创建了a去指向10。

int b = 10同样会检查栈中有没有10这个值,发现已经存在,则创建b指向已存在的10。在栈中,变量值是可以共享的。

b = 12检查栈中有没有12这个值,没有就创建一个12的值,再把b的指向12,这样也不会影响a的值。

说到String时,先说说JVM有一个常量存储区域,是用来存常量的,像代码定义直接双引号中的内容就是存在常量存储区域的。String不是基本变量类型。

String c = "hello"会先到常量存储区域找hello,如果没有,就在常量存储区域创建hello值,栈中创建一个c指向常量区域的hello。

String d = new String("hello")是new一String对象,会先到常量区域检查有没hello值,如果有,就在堆中生成hello的一个对象副本,如果没有就会在常量区先创建hello,再在堆中生成一个副本。在栈中生成d,指向堆中的hello对象,d是对象的引用。

User user = new User(10, "hello"),会构造函数,构造函数里的sid,sname是局部变量,会存储在栈中,指向的值是栈中的10和常量存储中的hello。在堆中会有new User这个对象,在栈中会有user这个对象的引用。这里要说一下,sid,sname是构造方法执行完后,会自动从栈中移除,而成员变量id,name是对象的属性,会在堆中存在,需要等JAVA自动回收机制进行回收。

当执行完test方法后,栈中的基础变量和值及对象引用都会被自动移除,释放内存。

通过例子应该可以比较好理解哪些数据存在堆中,哪些数据存在栈中了。

总结

堆分配内存时,大小和生存期都是不确定的,要生成的时候才知道,遵循先进先出的原则,读取速度比较慢。数据不能共享,每new一次都是一个新的对象。要由JAVA的垃圾回收机制来回收,所以容易造成内存多高。

栈分配内存时数据的大小和生存期是确定的,在编译时就知道了,遵循先进后出的原则,读取速度快,接近寄存器了。数据可以共享,节省内存,也比较快。在生存期结束后会自动释放,效率更高。

相关文章

  • Java堆栈的理解

    概述 先Copy一个概念:JVM是基于堆栈的虚拟机。JVM为每个新创建的线程都分配一个堆栈.也就是说,对于一个Ja...

  • java 堆栈,方法区理解

    转载 https://www.cnblogs.com/augus007/articles/10185796.html

  • JAVA堆栈

    最近在看JAVA虚拟机规范,谈下自己对java堆栈的理解 java虚拟机内存分为:栈、本地方法栈、堆、程序计数器、...

  • 堆栈区别

    理解不透彻,实在是无法写清楚,记录下过程吧 为了理解堆栈区别,我对比 c++,java,APP,javascipt...

  • Frida Hook

    - Hook Dlopen - Java堆栈打印 - Native堆栈打印 - HookJava中的loadLib...

  • android.os.DeadObjectException

    x5中的出错堆栈 其中堆栈中java.lang.RuntimeException:Package manager ...

  • Java堆栈

    JAVA在程序运行时,在内存中划分5片空间进行数据的存储。分别是:1:寄存器。2:本地方法区。3:方法区。4:栈。...

  • Java堆栈

    堆栈是JVM分配的两块内存空间 1.在方法中定义的一些基本类型和引用变量都在函数的栈内存分配,当超过变量的作用域之...

  • java 堆栈

    参考文章:1.JAVA 堆栈 堆 方法区 静态区 final static 内存分配 详解2.java里的静态成员...

  • Java 堆栈

    栈区:每个线程包含一个栈区,栈中只保存方法中(不包括对象的成员变量)的基础数据类型和自定义对象的引用(不是对象),...

网友评论

    本文标题:Java堆栈的理解

    本文链接:https://www.haomeiwen.com/subject/grounttx.html