面向对象是java的核心,
在学习面向对象时候,知道在创建对象时的内存图,
对学习面向对象有很大帮助,
下面有简到难给大家介绍下创建对象时候的内存分析,
随着学习的深入,以后的内存分析图会越来越详细.
栈:自动分配连续的空间,后进先出,放置局部变量
堆:不连续,放置new出来的对象
方法区:也是堆,放置类的代码信息,静态变量,常量池
一个对象,调用一个方法内存图:
这是一个对象调用一个方法的内存图,首先main方法先进栈,
通过new关键字创建一个手机的对象p,在堆内存中开辟一个空间,所有的属性都会创建,一开始所有的值都为默认值,
这个空间的首地址传递给p,
如果有赋值操作,通过p指向的地址,找到这个空间将值都传递给堆中的属性,
继续往下走,这个空间中有一个方法,方法都是运行在栈中,于是这个方法进栈,执行完了弹栈,
没有其他的方法,main方法结束
但是,这里依然有问题存在。创建多个对象时,如果每个对象内部都保存一份方法信息,这就非常浪费内存
了,因为所有对象的方法信息都是一样的。那么如何解决这个问题呢?请看如下图解。
多个对象,调用同一方法内存图
流程与上述类似,只是调用多次相同方法时,
为了避免开辟过多的空间,将方法的地址从方法区传递给堆中真实存在的对象,
常量和静态变量类似!!也是这么避免一直开辟空间!!!
补充:一个引用,作为参数传递到方法中内存图
我们知道,我们传递参数时候,可以传递任意类型的参数,所以,以上传递的都是基本数据类型的值,但是一个引用作为参数是如何传递到方法中的呢?请看下图:
在上述的基础上,参数p指向的也是phone的地址,所以可以直接使用p.属性来作为参数.
字符串在内存中的内存分析:
这个图是字符串在内存中的分析
对于字符串来说,直接用双引号创建的都是常量,相当于String的对象(或者说实例)
直接用双引号创建的都是存放在字符串常量池中通过地址到byte[]的地址,真实保存形式是以byte[]的形式保存的
未完待续中...励志整理出最完美的内存分析汇总