java程序是运行在jvm(java虚拟机)上的,因此Java的内存分配是在JVM中进行的。那么在程序内存分配上面,大致分为:本地方法栈、程序计数器、虚拟机栈、java堆、方法区。
栈(Stack):存放基本数据类型的数据、引用数据类型的变量名及对象的引用,但是引用的数据与对象并不放在栈中,而是放在堆中。
注:栈内存有一个很重要的特殊性——在栈中的数据可以共享
堆(Heap):存放引用数据类型的数据与new出来的对象,注意创建出来的对象只包含各自的成员变量,不包括成员方法。此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存。这一 点在Java虚拟机规范中的描述是:所有的对象实例以及数组都要在堆上分配。在堆中分配的内存,由JVM自动垃圾回收器来管理。
方法区(Method Area):存放静态的不变的资源。用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。
常量池:在JDK1.6及之前的版本,字符串常量池存放在方法区中间,在JDK1.7版本以后,字符串常量池就被移到堆中了。
{
在java编译后生成.class文件,会放在常量池中,每一个class文件都有一个对应的class常量池。 会存放基本数据类型的值 会存放被声明为final的常量
}
说明: 堆:凡是new出来的结构(对象、数组)都放在堆空间中。 对象的属性存放在堆空间中。 创建一个类的多个对象(比如p1、p2),则每个对象都拥有当前类的一套"副本"(即属 性)。当通过一个对象修改其属性时,不会影响其它对象此属性的值。 当声明一个新的变量使用现有的对象进行赋值时(比如p3 = p1),此时并没有在堆空间中创 建新的对象。而是两个变量共同指向了堆空间中同一个对象。当通过一个对象修改属性时, 会影响另外一个对象对此属性的调用。