本文是参考一篇博客以及自己的见解,做如下介绍。
JVM是Java程序和操作系统之间的桥梁,Java的内存分配都是在JVM上进行的。简单的说,一个Java程序在运行期间会涉及到以下内存区域:
1.寄存器,JVM内部虚拟寄存器,存取速度非常快,程序不可控制。
2.栈:保存局部变量的值,若局部变量是基本类型(byte、short、int、long、char、float、double、boolean),则直接存储在栈中。若局部变量是自定义类型,则栈中存放的是该类型的实例,即引用。当局部变量出了方法体,则自动销毁。
(1)栈中的数据可以共享。
例如:
int a = 1;
int b = 1;
编译器先创建一个a的引用,然后在栈中查找是否有1这个值,若存在,则将a指向1;若不存在,则将1存到栈中,并且将a指向1。紧接着创建b的引用,然后在栈中查找是否存在1,可以得知栈中存在,所以直接将b指向1。这时,如果再令 a=2;那么编译器会重新搜索栈中是否有2值,如果没有,则将2存放进来,并令a指向2;如果已经有了,则直接将a指向这个地址。因此a值的改变不会影响到b的值。
(2)Java中的数学计算是在栈中进行的
Integer i1 = new Integer(20);
Integer i2 = new Integer(30);
Integer i3 = new Integer(50);
System.out.println(i3 == i1+i2);
结果为true。在进行数学计算时,Java会进行自动拆箱,然后在栈中运行。20+30就是等于50,所以打印为true。
3.堆:用来存放动态产生的数据,保存一切new出来的对象和数组,由Java的垃圾回收机制自动回收,这个就导致了Java比较占内存的原因。
4:.常量池:JVM为每个已加载的类型维护一个常量池,常量池指的是在编译期被确定,除了包含代码中定义的各种基本类型和对象的常量值以外,还有一些以文本形式出现的符号引用。对于String类型的常量,JVM中是以表的形式存在的,有一张固定长度的表来存储字符串值。Java中的5中基本类型的包装类(Byte、Short、Integer、Long、Character)实现了常量池的技术,不过该包装类也只能针对-128~127之间的数进行管理。对大于127的数是没有用的。
例如:
Integer i1 = 10;
Integer i2 = 10;
System.out.println(i1==i2);
结果为true。
Integer i3 = 128;
Integer i4 = 128;
System.out.println(i3==i4);
结果为false。
参考文章:
Java内存分配全面解析----点击打开链接
深入Java核心 Java内存分配原理精讲(1)----http://developer.51cto.com/art/201009/225071.html
Java常量池--http://www.cnblogs.com/wenfeng762/archive/2011/08/14/2137820.html