java当中的内存分配

上传人:xiao****1972 文档编号:84822338 上传时间:2019-03-05 格式:DOC 页数:15 大小:288.50KB
返回 下载 相关 举报
java当中的内存分配_第1页
第1页 / 共15页
java当中的内存分配_第2页
第2页 / 共15页
java当中的内存分配_第3页
第3页 / 共15页
java当中的内存分配_第4页
第4页 / 共15页
java当中的内存分配_第5页
第5页 / 共15页
点击查看更多>>
资源描述

《java当中的内存分配》由会员分享,可在线阅读,更多相关《java当中的内存分配(15页珍藏版)》请在金锄头文库上搜索。

1、Java当中的内存分配以及值传递问题内存解析(2010-11-18 19:40:37)转载标签:java内存分配参数传递值传递问题内存解析分类:JavaSE首先必须说明作为Java程序员对于内存只要有大致的了解就可以了,如果你对Java当中的某一个知识点在不需要分析内存分配过程的情况下可以掌握,那就大可不必去研究内存。如果你对知识点已经掌握,那么你应该把更多的精力放在对业务逻辑的分析与设计上,这样的话你才可能这一行业走的更远。好了废话不多说了,下面我带着大家先来简单的看一下Java当中所涉及的内存分配,接着我会以讲解Java当中的值传递问题,分析在代码执行的过程当中内存的状态。一、Java当中

2、所涉及到的内存分类Java当中你知道这5种内存就够用了,下面对这5种内存里面所存放的数据做一解释。栈内存:它里面存放的是引用(也就是地址,Java当中的这个地址并非内存的物理地址,但是它通过这个地址找到它所指向地址的内容)还有就是基本类型的值以及方法的形参也是存放在栈内存当中的。对内存:它里面存放的是对象、引用、基本类型的值(对于引用和基本类型的值什么时候放在栈里什么时候放在堆里,在后面讲解Java当中的值传递问题,分析在代码执行的过程当中内存的状态的时候会说)。寄存器:它里面存放的是中间运算的数字(对于这个我们可以忽略不去考虑它)。代码段:顾名思义它里面放的就是程序的代码。池内存:池里面方的

3、是常驻内存反复利用的数据。好了这就是Java当中常见内存以及它里面所存放的数据,下面我们通过讲解Java当中的值传递问题,分析在代码执行的过程当中内存的状态。二、Java当中的值传递问题以及代码执行过程当中内存的状态什么是值传递?值传递就是Java当中参数传递的一种方式(而且也是唯一的一种方式,也就是说Java当中只有值传递),所谓参数传递就是在某个方法被调用的时候把一个实参传递给形参的过程。下面我们通过分析下面代码执行过称中内存的状态来说明Java当中的参数传递以及为什么Java当中只有值传递。代码清单:(为了节省空间格式不是很规范)定义学生类:定义测试类:测试结果:为什么会有这样的结果?下

4、面我们分析一下这段代码执行过称当中内存的分配,相信问题将迎刃而解。1、我们运行TestPassing这类,虚拟机加载TestPassing这个类,虚拟机将这些代码存放到代码段当中(这里我们就不画出代码段的图示了,后面虚拟机调用任何方法(包括构造方法)都要先到代码段中去找,但是这比较简单也不是重点接下来的解析当中如果涉及到方法调用就不再说明了),然后虚拟机从代码段当中找到main()方法,开始执行代码。此时虚拟机为main()创建栈内存,内存分配如下2、接着执行int age = 20;这行代码,由于它是基本类型的局部变量所以直接把它的值20存在栈内存名字叫age,内存分配如下3、接着执行Tes

5、tPassing tp =newTestPassing();这一行代码,这句话在内存当中做了3个操作,首先TestPassing tp,tp是一个引用类型的变量所以给它分配一块栈内存存放一个TestPassing对象的引用(也就是地址假设这个地址是ox 1a2b3c),接下来在堆内存创建一个TestPassing对象,接着把刚才栈里面tp的引用指向堆里面的这个TestPassing对象,这行代码的顺序之所以是这样是因为“=”的优先级比“new”的优先级低。内存分配如下(在此只给出最终内存分配图)4、接着执行这一行代码tp.addAge(age); TestPassing对象调用addAge(i

6、nt age)方法,虚拟机为addAge(int age)方法分配一个临时的栈内存,并且在这块临时栈内存当中为addAge(int age)的形参age也分配一小块栈内存,接着把main()当中的实参age的副本(注意是实参age的副本而不是实参age)传给形参age,由于实参age是基本类型所以实参age的副本就是20,也就是说把20传给形参age,此时的内存分配如下这行代码到此还没有执行完,参数传过去之后接着程序跳到被调方法当中去执行,也就是执行age+;此时操作的是形参age与实参age没有任何关系,age+;完了之后形参age的值变成21,此时的内存分配如下被调方法还没结束,程序接着往

7、下执行到方法体的结束大括号,被调方法执行完毕,同时addAge(int age)的临时栈内存关闭。此时的内存分配如下5、程序接着执行System.out.println(age= + age);(这一行代码的内存分配过程我想没人想让我画吧)这一行代码,很清楚看上面的内存图,也就不难理解为什么打印出20了。6、接下来程序执行到Student s1 =newStudent();这一行代码和上面TestPassing tp =newTestPassing();内存分配的过称基本一样,这句话也是在内存当中做了3个操作,首先Student s1,s1是一个引用类型的变量所以给它分配一块栈内存存放一个St

8、udent对象的引用(假设这个地址是ox1a2b3d),接下来在堆内存创建一个Student对象,它有一个int类型属性age,所以在刚才创建的对象的大块内存当中分出一小块来存放这个属性,里面存的值是0名在叫age(全局变量有默认值所以我们没给它赋值就默认为0),接着把刚才栈里面s1的引用指向堆里面的这个Student对象。此时的内存分配如下7、接着程序执行s1.age = 20;这一行代码,这行代码将堆内存当中的Student对象的age改为20,此时的内存分配如下8、接着程序执行tp.addAge(s1);这一行代码,TestPassing对象调用addAge(Student s)方法,虚

9、拟机为addAge(Student s)方法分配一个临时的栈内存,并且在这块临时栈内存当中为addAge(Student s)的形参s也分配一小块栈内存,接着把main()当中的实参s1的副本传给形参s,但是s1是引用类型它的副本就是它现在在栈内存里面的地址,也就是说把Student的地址传给形参s,所以形参就会根据这个地址找到Student对象,此时的内存分配如下这行代码到此还没有执行完,参数传过去之后接着程序跳到被调方法当中去执行,也就是执行s.age+;此时它操作的时是真正的Student对象,所以这行代码执行完了之后Student对象的age属性就变成了21,此时的内存分配如下被调方法

10、还没结束,程序接着往下执行到方法体的结束大括号,被调方法执行完毕,同时addAge(Student s)的临时栈内存关闭。此时的内存分配如下9、程序接着执行System.out.println(s1.age= + s1.age);这一行代码,很清楚看上面的内存图,也就不难理解为什么打印出21了。10、main()结束,main()栈内存关闭,没有任何引用指向堆内存当中的TestPassing对象和Student对象,垃圾回收器回收资源,虚拟机关闭。好了关于Java当中的内存分配以及值传递问题内存解析就说到这,Java当中的池内存也是一个很重要的概念,由于时间关系本次分析并未提及池内存,有时间再

11、给大家分享。可以给大家一个思考题,如果给addAge(intage)这个方法再加一String类型的形参也就是把这个方法改成addAge(intage, String name)并在这个方法里面改变name的值,给Student类再加一个属性String name,并在addAge(Student s)方法当中修改s.name的值,这样的话String是引用类型,那么name会怎样变呢?java的各类型数据在内存中分配情况详解分类:收藏文章2013-09-12 22:46192人阅读评论(0)收藏举报转载自:http:/ 内存中的堆(stack)与栈(heap)Java程序运行时有6个地方可以

12、存储数据,它们分别是寄存器、栈、堆、静态存储、常量存储和非RAM存储,主要是堆与栈的存储。【随机存储器 :Random Access Memory 】栈与堆都是Java用来在RAM中存放数据的地方。与C+不同,Java自动管理栈和堆,程序员不能直接地设置栈或堆。栈的优势是,存取速度比堆要快,仅次于直接位于CPU中的寄存器。另外,栈数据可以共享。但缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器,Java的垃圾收集器会自动收走这些不再使用的数据。但缺点是,由于要在运行时动态分配内存,存取速度较慢。【 寄存器位于CPU中】3

13、Java中数据在内存中的存储3.1基本数据类型的存储Java的基本数据类型共有8种,即int, short, long, byte, float, double,boolean, char(注意,并没有string的基本类型)。这种类型的定义是通过诸如int a = 3; long b =255L;的形式来定义的,称为自动变量。值得注意的是:自动变量存的是字面值,不是类的实例,即不是类的引用,这里并没有类的存在。如inta =3;这里的a是一个指向int类型的引用,指向3这个字面值。这些字面值的数据,由于大小可知,生存期可知(这些字面值固定定义在某个程序块里面,程序块退出后,字段值就消失了),

14、出于追求速度的原因,就存在于栈中。另外,栈有一个很重要的特殊性,就是存在栈中的数据可以共享。 假设我们同时定义:int a = 3; int b=3;编译器先处理int a =3;首先它会在栈中创建一个变量为a的引用,然后查找有没有字面值为3的地址,没找到,就开辟一个存放3这个字面值的地址,然后将a指向3的地址。接着处理int b =3;在创建完b这个引用变量后,由于在栈中已经有3这个字面值,便将b直接指向3的地址。这样,就出现了a与b同时均指向3的情况。【上文提到了引用+数值+内存地址这三个名词,其中变量名就是引用,给变量赋的值就是数值,而所提到的内存是抽象的内容,让引用指向的不是数值,而是存取数值的那块内存地址】定义完a与b的值后,再令a =4;那么,b不会等于4,还是等于3。在编译器内部,遇到时,它就会重新搜索栈中是否有4的字面值,如果没有,重新开辟地址存放4的值;如果已经有了,则直接将a指向这个地址。因此a值的改变不会影响到b的值。【定义变量,给变量赋值,然后在编译的过程中就可以将其保存在内存中了】3.2对象的内存模型在Java中,创建一个对象包括对象的声明和实例化两步,下面用一个例题来说明对象的内存模型。假设有类Rec

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 大杂烩/其它

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号