Java内存分配的时候一共涉及5个区域,分别是;寄存器、栈、堆、常量池、非RAM存储。
寄存器
寄存器是最快的存储区,位于处理器内部,由于寄存器的数量非常有限,所以寄存器都是按需分配,我们在程序中无法控制。
栈
栈位于通用RAM(随机访问存储器)中,栈由编译器自动分配和释放,栈存放的是基本数据类型(基本数据类型包括:int、short、double、long、float、boolean、char、byte;注意没有String)以及对象的引用。栈的优势是存取速度比堆快,仅次于CPU中的寄存器。另外,栈还有一个很大的特点就是栈中的数据可以共享,比如定义两个int类型的变量:int a = 3; int b = 3;这里a和b是一个指向int型的引用,指向"3"这个字面值。编译器先处理int a = 3;这句语句的时候,先在栈中创建一个变量为a的引用,然后查找有没字面值为3的地址,如果没有就开辟出一个存储3的地址,然后将a指向这个3对应的地址。接着处理int b = 3;,也是先创建一个变量b的引用,由于栈中已经有字面量3了,于是就把b也指向3对应的这个地址,所以a和b都指向了一个地址。当我们执行 b = 4;的时候,首先还是去栈中查找有没字面量值为4对应的地址,如果没有就开辟个,然后将b指向这个新开辟的地址。如果已经有了就直接将b指向这个地址,此时a还是指向3,但b指向4了,而且他俩不再指向同一个地址了。实际上形参,局部变量都存储在栈中。
堆
堆是一种通用的内存池,也位于RAM中,堆用于存储所有的java对象。
常量池
常量池用于存放常量
非RAM存储
非RAM存储用于存放持久化对象
下面来看个例子:
public class Student { /** * @author 行者摩罗 * @博客链接 http://blog.csdn.net/xingzhemoluo */ private int id; private String name; private int age; //get,set方法省略 public Student(int i,String n,int a) { this.id = i; this.name = n; this.age = a; } }
public class Test { public void update (int x) { x = 100; } public static void main(String[] args) { int score = 99; Test test = new Test(); test.update(score); Student student = new Student(1,"行者摩罗",23); } }在这段代码中,score是局部变量,i、n、a、x都是形参,形参也属于局部变量,id、name、age为成员变量。当从main方法开始运行的时候,
①int score = 99; score是局部变量,引用(score)和值(99)都存储在栈中。
②Test test = new Test(); test是个引用,存放于栈中,new Test()创建出来的对象存在于堆中。
③test.update(score); update()方法里的形参x是局部变量,引用和值都存在于栈中,当update方法执行完毕以后,x会自动从栈中消失。
④Student student = new Student(1,"行者摩罗",23); student为引用,存放于栈中,new Student(1,"行者摩罗",23)创建出来的对象存在于堆中。其中i、n、a为形参,存在于栈中,name,id,age为成员变量,他们对应的值存储于堆中(在new Student()里面)。当Student构造方法执行完毕以后,i、n、a会自动从栈中消失。
⑤main方法执行完毕以后,score、test、student都会自动从栈中消失,new Test()以及new Student(1,"行者摩罗",23)则由垃圾回收期来回收。
参考资料:http://blog.csdn.net/rj042/article/details/6871030
http://blog.csdn.net/cuixianpeng/article/details/6892043
声明:
1.原创内容,转载请注明原文链接
2.摩罗不写博客,所有内容只是摩罗笔记,如有错误或者您有更好的意见,欢迎指正。
欢迎关注行者摩罗微信公众号(xingzhemoluo),共同交流编程经验,扫描下方二维码即可;
原文:http://blog.csdn.net/xingzhemoluo/article/details/40050025