使用Quota管理磁盘配额
2015-08-06 17:47
357 查看
以前自己就没怎么搞清楚值传递与引用传递的内部机制,近来发现好多面试题中都考到了它,决定真正弄懂它,所以在网上查了很多资料,最后再结合自己的理解,写一篇文件来做一下总结。
这里就结合一个常见的例子来做解析,User类源码如下:
再写一个测试类UserTest:
为了真正弄清楚程序的执行过程,我觉得得先明白几个东西,也就是下面这张图里面的内容:
下面再来讲解程序在内存中的执行过程,首先从main函数的第一行开始,创建了一个UserTest对象,变量test指向了新new出来的UserTest对象,通过上面知道,局部变量存放在栈空间,所以执行完这句,在栈中就给test变量分配了一小块空间,同时在堆内存中也分配了一块空间用来存放new出来的UserTest对象,test指向了堆中对象,这就是所谓的引用;再往下面给一个变量赋值,同样是一个变量,在栈中分配一块空间,变量名为n,类型为int,值为2;下面创建了一个User对象,栈中给u1变量分配空间,堆中也分配一块内存给new出来的User对象,同样u1也指向了堆中new出来的User对象,这个对象中有两个成员变量id和name,但创建这个对象的时候,我们调用了这个对象的有参构造方法:
那么方法是怎么执行的呢?方法里面的开参跟局部变量同等对待,在栈中分配_id和_name空间,它们的值分别是20和"Boy",然后通过赋值,就把它们的值传递给了User对象中的id和name,当这个方法构造方法调用完毕后,分配给这个方法的参数和内存全部消失,然后再给让其它人用。那么这个过程的执行流程图如下:
我觉得这个内存的分析,对我们学习程序是很有帮助的,我相信只要弄懂了内存,以后这方面再怎么样的面试题都难不到了。另外还要强调的是:
1.先要弄清程序存放在内存的哪些地方。
2.局部变量的存放位置,尤其方法里面的参数,方法执行完毕,为这个方法分配的参数和内存都将消失,把空间让给别人用。
3.新new出来的对象一定是放在堆中,如果一个对象没有了引用,也就会在适时被垃圾回收掉。
4.这个东西最好是自己动手画一画,一动手可能就全明白了。
由于程序执行是一个动态的过程,如果用语言描述清楚,需要花大量的篇幅,写了之后别人也不一定能看的懂,所以我做了一个PPT,比较全面的描述了这个程序在内存中的执行过程,不过由于本人PPT技术不咋的(呵呵),做的比较粗糙,希望大家都能看的懂。这篇文章是自己看过一些资料后的总结,自己难免会有理解疏漏的地方,希望大家不吝赐教。
这里就结合一个常见的例子来做解析,User类源码如下:
class User { private int id; private String name; public User(int _id, String _name) { id=_id; name=_name; } public void setId(int $id) { id=$id; } public void setName(String $name) { name=$name; } public int getId() { return id; } public String getName() { return name; } public String toString() { return id+" - "+name; } }
再写一个测试类UserTest:
public class UserTest { public static void main( String[] args) { UserTest test=new UserTest(); int n=2; User u1=new User(20,"Boy"); User u2=new User(21,"Girl"); test. changeId (n); System.out.println ( "n is " + n); test.changeName(u1); test.changeIdName(u2); System.out.println(u1.toString()); System.out.println(u2.toString()); } public void changeId(int i) { i=3; } public void changeName( User u) { u=new User(1,"Test"); } public void changeIdName( User u) { u.setId(23); u.setName ("My Name"); } }
为了真正弄清楚程序的执行过程,我觉得得先明白几个东西,也就是下面这张图里面的内容:
下面再来讲解程序在内存中的执行过程,首先从main函数的第一行开始,创建了一个UserTest对象,变量test指向了新new出来的UserTest对象,通过上面知道,局部变量存放在栈空间,所以执行完这句,在栈中就给test变量分配了一小块空间,同时在堆内存中也分配了一块空间用来存放new出来的UserTest对象,test指向了堆中对象,这就是所谓的引用;再往下面给一个变量赋值,同样是一个变量,在栈中分配一块空间,变量名为n,类型为int,值为2;下面创建了一个User对象,栈中给u1变量分配空间,堆中也分配一块内存给new出来的User对象,同样u1也指向了堆中new出来的User对象,这个对象中有两个成员变量id和name,但创建这个对象的时候,我们调用了这个对象的有参构造方法:
public User(int _id,String _name) { id=_id; name=_name; }
那么方法是怎么执行的呢?方法里面的开参跟局部变量同等对待,在栈中分配_id和_name空间,它们的值分别是20和"Boy",然后通过赋值,就把它们的值传递给了User对象中的id和name,当这个方法构造方法调用完毕后,分配给这个方法的参数和内存全部消失,然后再给让其它人用。那么这个过程的执行流程图如下:
我觉得这个内存的分析,对我们学习程序是很有帮助的,我相信只要弄懂了内存,以后这方面再怎么样的面试题都难不到了。另外还要强调的是:
1.先要弄清程序存放在内存的哪些地方。
2.局部变量的存放位置,尤其方法里面的参数,方法执行完毕,为这个方法分配的参数和内存都将消失,把空间让给别人用。
3.新new出来的对象一定是放在堆中,如果一个对象没有了引用,也就会在适时被垃圾回收掉。
4.这个东西最好是自己动手画一画,一动手可能就全明白了。
由于程序执行是一个动态的过程,如果用语言描述清楚,需要花大量的篇幅,写了之后别人也不一定能看的懂,所以我做了一个PPT,比较全面的描述了这个程序在内存中的执行过程,不过由于本人PPT技术不咋的(呵呵),做的比较粗糙,希望大家都能看的懂。这篇文章是自己看过一些资料后的总结,自己难免会有理解疏漏的地方,希望大家不吝赐教。
相关文章推荐
- 【十七】关于ACL、Squid等。
- 好的博客链接
- Android的屏幕适配
- hdu 1181 变形课(dfs)
- NDK crash栈信息的错误定位
- getMeasuredHeight(),getScrollY(),getHeight()的区别
- 【Qt OpenGL教程】19:粒子系统
- iOS开发中isKindOfClass和isMemberOfClass的区别
- eclipse构建及运行maven web项目
- IOS-页面跳转及动画-1
- 脚本实现mysql周完全备份所有库
- makecc 命令未找到的解决方法
- app后端搭建聊天服务器的经历
- grep用法总结
- js 实现replaceAll
- android锁屏(中)
- unity AssetBundle的资源管理
- Highcharts 静态分页
- iOS设计模式之代理模式
- visual studio 自定义警告标签