一. Java内存的分配

当Java 程序运行时,对空间进行了不同区域的划分,因为每一片区域都有特定的处理数据方式和内存管理方式。

        1. :储存局部变量 (基本数据类型的值;类的实例,即堆区对象的引用(指针);

            特点:栈内的数据用完就释放掉

        2. :储存 new 出来的对象(即对象实例)及数组 ;

                注:

                        jdk 1.7常量属于堆内存的一部分。

                        Java8移除了永久代并由元空间(metaspace)代替,存放在本地内存(native space)中。并没有对常量池再做变动。即常量池一直在堆中。

            特点:(1)new出来的变量都是有地址值的

                       (2)每一个变量都有默认值:

                                byte,short,int ,long : 0;

                                float,double:0.0;

                                Boolean:false ;

                                引用类型:null;

                       (3)new出来的对象,使用完毕,会被垃圾回收器回收。

          3. 常量池:常量池本身是方法区中的一个数据结构。

                  Java中的常量池,实际上分为两种形态:静态常量池运行时常量池

                     静态常量池,即*.class文件中的常量池,占用class文件绝大部分空间。

                     运行时常量池,则是jvm虚拟机在完成类装载操作后,将class文件中的常量池载入内存中,并保存在方法区中,我们常说的常量池,就是指方法区中的运行时常量池

                常量池的好处
                常量池是为了避免频繁的创建和销毁对象而影响系统性能,其实现了对象的共享。
              例如字符串常量池,在编译阶段就把所有的字符串文字放到一个常量池中。
                (1)节省内存空间:常量池中所有相同的字符串常量被合并,只占用一个空间。
                (2)节省运行时间:比较字符串时,==比equals()快。

                对于两个引用变量,只用==判断引用是否相等,也就可以判断实际值是否相等。

          4. 方法区:存放类信息和运行时常量池。

                注: java8中,方法区存放于元空间(Metaspace),直接存放于本地内存

java各个类型所占的内存的大小 java基本类型内存分配_方法区

                 说明:

                        字面量:java代码在编译过程中是无法构建引用的,字面量就是在编译时对于数据的一种表示:                 int a = 1; //这个1便是字面量

                        符号引用:由于在编译过程中并不知道每个类的地址,因为可能这个类还没有加载,所以如果你在一个类中引用了另一个类,那么你完全无法知道他的内存地址,只能用他的类名作为符号引用,在类加载完后用这个符号引用去获取他的内存地址。

java各个类型所占的内存的大小 java基本类型内存分配_Java_02

                   说明:

                        PC寄存器/程序计数器是jvm执行程序的流水线,存放一些跳转指令。

                        本地方法栈是jvm调用操作系统方法所使用的栈。

                        字符串常量池原本存放于方法区,jdk7开始放置于堆中。存储的是string对象的直接引用,而不是直接存放的对象,是一张string table

                        静态变量是有static修饰的变量,jdk7时从方法区迁移至堆中