您的位置:首页 > 其它

学习笔记---------面向对象的内存分析

2017-06-16 23:51 316 查看
内存分为两大块栈和堆。

栈:

栈中保存的是Java八种基本数据类型的变量(short, int, long, byte, double, float, char, boolean),引用数据类型的局部变量,对象的引用变量(相当于对象实例或者数组的名字)。当程序员在代码中定义了上述类型的变量时,JVM就会在栈内存中为这些变量分配空间。

栈有一个很重要的特殊性,就是存在栈中的数据可以共享。比如:
我们同时定义:

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的值。

需要注意的是:1.引用变量保存的是对象的实例或数组在堆内存中的地址。

 2.栈内存是线程私有的。JVM为每一个线程分配一个栈,这个栈的生命周期与线程相同。

堆:

堆里包含了一块特殊的区域“方法区”,它存储的是被加载的类信息,常量池,方法列表,静态变量和new出来的对象和数组。

与栈不同,在多线程开发中,堆内的数据是所有线程栈共享的(并非为每一个线程开辟出一块堆内存)。

方法区和堆内存是一样是各个线程共享的,方法区的大小并非固定的,可以根据需要进行动态调整。
方法区的内存地址空间也不必须是连续的,JVM允许用户和程序制定方法区的初始大小,最大和最小尺寸。
其中,类信息包含了类和接口的名称。在方法区中,每一个类都维护着一个被称作常量池的一块内存区,存储的是String, Integer, floating point等类型的常量。这些数据和堆内存中的对象实例与数组一样,是通过内存地址来引用的。方法列表中保存着方法的名称已及它的描述符。
关于栈和堆的访问速度,访问栈的速度要略快于访问堆的速度,尽管二者都是内存,在物理上的访问机制相同,但访问方式并不相同。
访问堆内存中的内容通常需要两次访问:第一次取得值得地址(引用变量),第二次获取堆内存的值。而取得栈内存中的内容只需要一次访问。

未完待续。。。。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: