中栈、堆和常量池
内存分配
寄存器:我们在程序中无法控制
栈:存放基本类型的数据和对象的引用,但对象本身不存放在栈中,而是存
放在堆中
堆:存放用 产生的数据
静态域:存放在对象中用 定义的静态成员
常量池:存放常量
非 存储:硬盘等永久存储空间
在函数中定义的一些基本类型的变量数据和对象的引用变量都在函数的栈内
存中分配。
当在一段代码块定义一个变量时, 就在栈中为这个变量分配内存空间,当
该变量退出该作用域后, 会自动释放掉为该变量所分配的内存空间,该内
存空间可以立即被另作他用。
堆内存用来存放由 创建的对象和数组。 在堆中分配的内存,由 虚
拟机的自动垃圾回收器来管理。
在堆中产生了一个数组或对象后,还可以在栈中定义一个特殊的变量,让栈中
这个变量的取值等于数组或对象在堆内存中的首地址,栈中的这个变量就成了
数组或对象的引用变量。 引用变量就相当于是为数组或对象起的一个名称,以
后就可以在程序中使用栈中的引用变量来访问堆中的数组或对象。引用变量就
相当于是为 数组或者对象起的一个名称。引用变量是普通的变量,定义时在栈
中分配,引用变量在程序运行到其作用域之外后被释放。而数组和对象本身在
堆中分配,即使程序运行到使用 产生数组或者对象的语句所在的代码块
之外,数组和对象本身占据的内存不会被释放,数组和对象在没有引用变量指
向它的时候,才变为垃圾,不能在被使用,但仍然占据内存空间不放,在随后
的一个不确定的时间被垃圾回收器收走(释放掉)。这也是 比较占内存
的原因。
实际上,栈中的变量指向堆内存中的变量,这就是 中的指针!
常量池指的是在编译期被确定,并被保存在已编译的
文件中的一些数据。除了包含代码中所定义的各种基本类型(如 、 等
等)和对象型(如 及数组)的常量值!还包含一些以文本形式出现
的符号引用,比如: 类和接口的全限定名; 字段的名称和描述符; 方法和名
称和描述符。 虚拟机必须为每个被装载的类型维护一个常量池。常量池就是该
类型所用到常量的一个有序集和,包括直接常量( " 和 #
常量)和对其他类型,字段和方法的符号引用。对于 常量,它的
值是在常量池中的。而 $ 中的常量池在内存当中是以表的形式存在的,对于
类型,有一张固定长度的 %&'('() )* 表用来存储文字字