zoukankan      html  css  js  c++  java
  • 堆和栈的区别

    1.从存储角度来看,堆内存主要用于存储实例对象和JRE classes,占内存用于存储基本类型变量和对象的引用

    2.从存取速度来看,栈存取速度快,堆存取速度比较慢,因为要在运行时动态分配内存,存取速度较慢

    3.从线程的角度来看,每个线程都有一个自己的JAVA栈,所有线程共享一个堆。在JVM中,内存被分为线程栈区和堆区

    4.从GC看来,栈区GC比较频繁,堆区GC不频繁。

    注:堆的结构为链表,堆会产生内存碎片。

      堆会产生内存泄漏:已分配的内存无法释放,积累就会形成

      栈可能回产生内存溢出

      递归:容易造成栈溢出

      JavaScript:容造成内存泄漏

    5.内存查找规则

    5.1取值时:

      所有变量都从栈里开始找

      如果栈里没有,试图补this

    5.2方法调用规则:

      (1)增加隔板

      (2)传输this

      (3)传输参数

    5.3调用结束时

      (1)删除所有的变量

      (2)传输返回值

      (30去掉隔板)

    6.关于JAVA中String类以形参传递到函数里面,修改后外面引用不能获取到更改后的值(转https://www.cnblogs.com/ytjava/p/7360109.html)

    String类的存储是通过final修饰的char[]数组来存放结果的。不可更改。所以每次当外部一个String类型的引用传递到方法内部时候,只是把外部String类型变量的引用传递给了方法参数变量。对的。外部String变量和方法参数变量都是实际char[]数组的引用而已。所以当我们在方法内部改变这个参数的引用时候,因为char[]数组不可改变,所以每次新建变量都是新建一个新的String实例。很显然外部String类型变量没有指向新的String实例。所以也就不会获取到新的更改。 
    下面程序例子假定tString指向A内存空间,A内存空间存放了”hello”这个字符串,然后调用modst函数将tString引用赋值给了text引用,注意是引用。确实是传址,我们知道String是不可变的,任何进行更改的操作都会产生新的String实例。所以在方法里面text指向了B空间,B空间存放了”sdf” 字符串,但是这个时候tString还是指向A空间,并没有指向B空间。

    两次输出结果都是:

    7.java中对象作为方法的入参时,这个入参是否会在栈和堆中创建临时的对象

    package com.entity;
    
    public class RefDemo03 {
    
        public static void main(String args[]){ 
            Demo d1 = new Demo() ; 
            d1.temp = "world" ; 
            //打印word
            System.out.println("fun()调用前:" +d1.temp) ; 
            fun(d1) ; 
            //打印JAVA
            System.out.println("fun()调用:" + d1.temp) ; 
            Demo d3 = new Demo();
            //打印hello
            System.out.println("第二次new的对象"+d3.temp);
        }
    
        
        
        public static void fun(Demo d2){ //d2会不在栈中创建对象,并在堆中分配内存给d2使用?
            d2.temp = "JAVA"; 
        }
    
    }
    class Demo{
        String temp = "hello" ; 
    }

    输出结果为:

    fun()调用前:world
    fun()调用:JAVA
    第二次new的对象hello

    总结:

    当new一个对象的时候,java在堆对对象分配内存,在栈中定义一个特殊的变量,这个变量的取值等于对象在堆内存中的首地址。因此,单对象入参的时候,d2也是在栈中定义一个保存内存首地址的变量而已,这个地址指向原先在堆中被分配的内存。因此,在方法中对对象的操作是直接操作原有的对象,而不会在堆中分配而外的内存。也就是d1和d2指向的是同一个内存地址

    8.关于String类型的内存指引可参考:

    https://www.cnblogs.com/iyangyuan/p/4631696.html

     

  • 相关阅读:
    java----设计模式--创建型模式(GOF23)
    java----作用域
    java和python对比----实例化的对象属性:
    java----关键字
    java----Java的栈,堆,代码,静态存储区的存储顺序和位置
    java----面对对象
    算法----取0~30不重复的10个整数
    算法----二分查找算法
    织梦 验证码不显示问题
    dedecms 后台修改系统设置,但是config.cache.inc.php文件不能写入
  • 原文地址:https://www.cnblogs.com/gxlaqj/p/11394388.html
Copyright © 2011-2022 走看看