笔记_Java内存分配

《Java内存分配》

 

Java内存分配和管理是Java的核心技术之一。涉及以下:栈、堆、常量池、静态域。

  1.  常量池:constant pool。指在编译期被确定,并被保存在已编译的.class文件中的一些数据。是个有序集合,以表的形式。主要包括:

    a) 用final定义的常量。可以是基本数据类型(int、long等),是对象型(数组等)。

b) 类、接口、字段、方法的名字和描述符。

注意的是,String作为特殊的类型,若初始化方式是String a = "abc",则"abc"是存于常量池中的,即String字符串是不可变的。而String a = new String("abc")则不同。

  2.  静态域:存放在队形中用static定义的成员。

  3.  栈:使用上特点是读取速度快,但是只能存定长的、不可变的数据。

    当在一段代码块定义一个变量时,Java就在栈中为这个变量分配内存空间;当该变量退出该作用域后,Java会自动释放掉为该变量所分配的内存空间,该内存空间立即被另作他用。主要包括:

a) 基本数据类型的变量及其数据

    eg:int a = 9。a和9都存在栈中,并且a指向9。注意,当同时有int b = 9时,则只存入b并指向9;当a的值改变,如下面有a = 10,则存入10并让a指向10。基本数据变量的这种储存方式,与引用变量完全不同。

 b) 引用数据类型(即,对象)的引用变量。

     引用变量是一个内存地址(Java指针),指向该对象在堆中储存的数据的首地址。

  4.  堆:用来存放new出来的对象和数组。

    引用变量在程序运行到其该作用域之外时,Java会自动释放掉栈中的引用变量;注意,堆中的数据不会立即被释放;在堆中分配的内存,由GC(JVM垃圾自动回收器)来不定期回收。

   5. String的存储方式:String包装类比较特殊,跟基本数据类型和对象的存储方式都不同,而且初始化方式、+连接运算符等会有特殊的处理方式。

初始化时,其引用存于,但是数据可能存放在常量池中(编译时就已创建好),有的存放在堆中(运行时才被创建)。

eg:String a = "hello";

String b = "hello";

System.out.println(a == b);   //true

上例,这种初始化方式,"hello"存放于常量池中,a和b都指向它。

eg:String a = new String("hello");

String b = new String ("hello");

System.out.println(a == b);   //false

System.out.println(a.equals(b));   //true

上例,两次初始化new了两个对象,堆中没有常量池或栈的那种机制,不会判断两次new的对象的数据是否相等,所以是false。

注意:a.equals(b)取决于是否重写了equals方法,Object类的默认equals()方法比较的就是a == b;String重写了equals方法。

 

    6. 值传递和引用传递:跟上述内存分配机制密切相关,总结为:

a. 值传递(传递的是拷贝):基本数据类型 和 String的直接复制情况。(即常量池)

b. 引用传递(传递的是引用&指针&内存地址):引用数据类型。


猜你喜欢

转载自blog.csdn.net/na_simon2900086/article/details/53167386
今日推荐