一、认识Android储存结构

对于Android来说,存储主要分为三个部分:内存、内部存储以及外部存储,详细介绍如下:

(1)内存存储RAM(Random Access Memory)
内存与PC的内存是一样的,是用来运行程序,不能用来永久存储数据,手机一旦关机,在内存中的所有数据都将会丢失,内存也是现在人类制造的所有电子设备所必需拥有的。

(2)内部存储ROM(Read Only Memory)
就是就相当于是PC中的硬盘的角色。用于存储Andoid 设备的操作系统和应用程序的存储介质。也就是说,Android设备中的Android系统和应用程序(APK文件)都是存在内部存储区的。例如手机的/system/目录、/data/目录等。

(3)外部存储区
相当于PC中的U盘或者移动硬盘,SD Card等。

由于Android设备通常会将内部存储器芯片固定在芯片上,所以一般无法更换内部存储器的。 为了增强Android设备的存储能力,很多Android设备都支持扩展的SD卡功能(通常称之为MicroSD类型的存储卡)。所以我们经常说的4GB+64GB或者 4GB+128GB是指 内存是4GB大小、内部存储大小为64GB或者128GB大小。

二、 Java内存结构

1、栈区(stack),由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。
2、堆区(heap),一般由程序员分配释放, 若程序员不释放,JVM不定时观察发现没有引用指向时会GC回收 。
3、静态区(static storage),存放由static修饰的静态成员。 程序结束后由系统释放。
4、常量区(constant storage),基础类型、字符串等就是放在这里的。常量存储位于堆中。程序结束后由系统释放 。
5、代码区,存放函数体的二进制代码,而且是多个对象共享代码空间区域。

基本数据类型存在栈(stack), 引用数据类型存在堆(heap)。java数据类型结构图:

                               ┏数值型━┳━整数型:byte short int long              ┏基本数据类型━━┫       ┗━浮点型:float double              ┃               ┣字符型:char                                          数据类型   ╋              ┗布尔型:boolean                            ┃               ┏类(class)              ┗引用数据类型━━╋接口(interface)                               ┗数组(array)

基本数据类型和引用数据类型的区别:

(1)从概念方面来说:
基本数据类型:变量名指向具体的数值;
引用数据类型:变量名指向存数据对象的内存地址,即变量名指向hash值。

(2)内存构建方面来说:
基本数据类型:变量在声明之后java就会立刻分配给他内存空间;
引用数据类型:这类变量声明时不会分配内存,只是存储了一个内存地址。

(3)从使用方面来说:
基本数据类型:使用时需要赋具体值,判断时使用“==”号;
引用数据类型:使用时可以赋null,判断时使用equals方法。

(4)从局部声明来说:(即局部变量)

基本数据类型:所声明的变量名及值都是放在方法栈中;

引用数据类型:所声明的变量(内存地址值)是放在方法的栈中,该变量所指向的对象实际是放在堆内存中。

(5)从全局声明来说:(即全局变量)

基本数据类型:所声明的变量名及其值放在堆内存中;

引用数据类型:所声明的变量(内存地址值)指向所引用的对象。该变量名和对象都存储在相应的堆内存中。

三、 堆和栈的区别

栈与堆都是Java用来在Ram中存放数据的地方。与C++不同,Java自动管理栈和堆,程序员不能直接地设置栈或堆。
Java的堆是一个运行时数据区,类的对象从中分配空间。这些对象通过new、new array、anewarray和 multianewarray等指令建立,它们不需要程序代码来显式的释放。堆是由垃圾回收来负责的,堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器,因为它是在运行时动态分配内存的,Java的垃圾收集器会自动收走这些不再使用的数据。但缺点是,由于要在运行时动态分配内存,存取速度较慢。
Java的栈存取速度比堆要快,仅次于寄存器,栈数据可以共享。但缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。栈中主要存放一些基本类型的变量(int, short, long, byte, float, double, boolean, char)和对象句柄。栈有一个很重要的特殊性,就是存在栈中的数据可以共享。例如:

int a = 3;int b = 3;

编译器先处理int a = 3;首先它会在栈中创建一个变量为a的引用,然后查找栈中是否有3这个值,如果没找到,就将3存放进来,然后将a指向3。接着处理int b = 3;在创建完b的引用变量后,因为在栈中已经有3这个值,便将b直接指向3。这样,就出现了a与b同时均指向3的情况,就可以使用 == 进行比较。另外,a的值改变并不影响到b的值,如果令a = 4;那么编译器会重新搜索栈中是否有4值,如果没有,则将4存放进来,并令a指向4;如果已经有了,则直接将 a 指向这个地址即可。
来一段代码进行分析:

public class Test {String a = "123456";    //值在常量池中    String b = "123456";   // a == b true 引用地址相同。因为值在常量池中已存在,所以两个变量指向的是同一个对象。final int A = 0; //final常量,堆中String[] c=new String[5]; // 手动分配new创建对象,在堆中    tatic int d =0; //静态区public static void main(String args[]) () {//方法栈    a = new String("123"); //创建了两个String对象,一个存于常量池中,一个于堆内存中且由a指向。        b = new String("123");//创建一个对象在堆内存中由b指向。因为常量池中已经存在"123"对象。String c = "123"; //值“123”在常量池堆中已存在。变量}}

例如:String a = “123456”; // 引用对象 a ,值 123456 在常量池中。为什么呢?

因为,基本数据类型存在栈(stack), String的对象实例存在堆(heap)。基础数据类型在栈里面直接分配内存 ,而引用数据则是通过堆里的对象来对栈中的内容进行引用。在 java 中 String 是个对象,是引用类型不是基本数据类型,判断是否相等,不能使用==,而使用equals方法。java中对 String 对象特殊对待,在堆区域给分成了两块,一块是 String constant pool(存储java字符串常量对象),另一块用于存储普通对象及字符串对象。另外,java虚拟机处理基础类型与引用类型的方式是不一样的,对于基本类型,java虚拟机会为其分配数据类型实际占用的内存空间;而对于引用类型变量,它仅仅是一个指向堆区中某个实例的指针。

字符串在内存中的存储情况如下所示:

String s1 = "abc";    String s2 = "xyz";    String s3 = "123";    String s4 = "A";    String s5 = newString("abc");     char[] c = {'J','A','V','A'};     String s6 = newString(c);      String s7 = newString(newStringBuffer());  

更多相关文章

  1. Android(安卓)AlertDialog的一切
  2. android 数据传递详解(Serialization、Parcelable、Parcel、Inten
  3. Android基础知识学习-Instrumentation启动源码简析
  4. Android(安卓)Handler 机制以及各方法所在线程原理分析
  5. greenDAO系列3--又是介绍
  6. Android之利用SQLite数据库实现登陆和注册
  7. Android(安卓)Intent学习笔记
  8. V8和JavaScriptCore在Android(安卓)Froyo上的速度比较
  9. Android(安卓)之 Service服务介绍

随机推荐

  1. Android(安卓)记住密码功能
  2. Ubuntu下编译android的linux内核
  3. Bluetooth in Android(安卓)4.2 and 4.3(
  4. Android下面的MD5加密
  5. build.prop生成及参数解析
  6. 深入理解数据结构
  7. android findViewById
  8. 手机安全卫士06
  9. Android(安卓)Handler
  10. Android的onCreateOptionsMenu()创建菜单