java初学者笔记之2.内存解析


内存结构

引入

在程序运行时,对象是如何放置安排计的呢?算机内存是如何分配的呢?弄清楚这些问题将会使你的java水平提高一大块

 

计算机中6个可以存储数据的地方

      寄存器 

由于它位于计算机的处理器的内部

所以它是计算机中读取数据最快的存储区域,

但是寄存器的空间和数量及其有限

所以寄存器由编译器根据需求进行分配

由于你将不可能直接控制寄存器

所以也不会在程序中感觉到寄存器的任何迹象

   堆栈(执行程序)

                     存储方式:

                     Windows, 栈是向低地址扩展的数据结构,是一块连续的内存的区域。这句话的意思是栈顶的地址和栈的最大容量是系统预先规定好的,在WINDOWS下,栈的大小是固定 的(是一个编译时就确定的常数),如果申请的空间超过栈的剩余空间时,将提示overflow。因此,能从栈获得的空间较小。只要栈的剩余空间大于所申请 空间,系统将为程序提供内存,否则将报异常提示栈溢出。 由系统自动分配,速度较快。但程序员是无法控制的。

 

                     原理 :栈式存储分配要求在过程的入口处必须知道所有的存储要求

                                   栈式存储分配按照先进后出的原则进行分配

 

                     由于它位于计算机通用RAM(随机访问存储器)

                     所以它在计算机中读取速度仅低于寄存器

                     由于它通过堆栈指针上下移动的方式来释放或分配内存空间

                     然而在创建程序的时候java编译器必须要知道存储在堆栈空间的所有数据确切的大小和生命周期,因为他必须生成相应的代码来上下移动指针

                     因而限制了程序的灵活性

                     所以一般将java对象的引用基本数据类型保存在这里

                     Java自动管理堆栈,程序员不能直接地设置栈

                     数据可以共享

int a = 3;
int b = 3

编译器先处理int a = 3;首先它会在栈中创建一个变量为a的引用,然后查找栈中是否有3这个值,如果没找到,就将3存放进来,然后将a指向3。接着处理int b = 3;在创建完b的引用变量后,因为在栈中已经有3这个值,便将b直接指向3。这样,就出现了ab同时均指向3的情况。这时,如果再令a=4;那么编译器 会重新搜索栈中是否有4值,如果没有,则将4存放进来,并令a指向4;如果已经有了,则直接将a指向这个地址。因此a值的改变不会影响到b的值。要注意这 种数据的共享与两个对象的引用同时指向一个对象的这种共享是不同的,因为这种情况a的修改并不会影响到b, 它是由编译器完成的,它有利于节省空间。而一个对象引用变量修改了这个对象的内部状态,会影响到另一个对象引用变量。

   堆 (存放对象)

                     存储方式:

                                   堆空间的话操作系统 一个记录空闲内存地址的链表,当系统收到程序的申请时,会遍历该链表,寻找第一个空间大于所申请空间的堆结点,然后将该结点从空闲结点链表中删除,并将该 结点的空间分配给程序。另外,对于大多数系统,会在这块内存空间中的首地址处记录本次分配的大小,这样代码中的delete语句才能正确的释放本内存空 间。另外由于找到的堆结点的大小不一定正好等于申请的大小,系统会自动的将多余的那部分重新放入空闲链表中。是由new分配的内存,一般速度比较慢,而且 容易产生内存碎片,不过用起来最方便。另外,在WINDOWS下,最好的方式是用VirtualAlloc分配内存,他不是在堆,也不是在栈是直接在进程的地址空间中保留一快内存,虽然用起来最不方便。但是速度快,也最灵活。是向高地址扩展的数据结构,是不连续的内存区域。这是由于系统是用链表来存储的空闲内存地址的,自然是不连续的,而链表的遍历方向是由低地址向高地址。堆的大小受限于计算机系统中有效的虚拟内存。由此可见,堆获得的空间比较灵活,也比较大

 

                     原理 :堆式存储分配则专门负责在编 译时或运行时 模块入口处都无法确定存储要求的数据结构的内存分配

                    

                           

                     通用性的内存池

                     也存放在RAM

                     然而好处在于编译器不需要知道从堆中分配具体多少内存空间也不需要知道它的生命周期,Java的垃圾收集器会自动收走这些不再使用的数据

                     因而就增加了程序的灵活性

                     但是代价是降低了读取速度,他的读取速度将低于堆栈的读取速度

                     所以一般程序将 new 出来的对象和数组放入堆空间,堆空间将会根据对象性质自动分配内存的大小

                     Java自动管理堆,堆是由垃圾回收来负责的,程序员不能直接地设置堆

                    

                     面向对象的多态性,堆内存分配是必不可少的,因为多态变量所需的存储空间只有在运行时创建了对象之后才能确定

   静态存储

原理: 静态存储分配要求在编译时能知道所有变量的存储要求

要求程序代码中不允许有可变数据结构(比如可变数组)的存在,也不允许有嵌套或者递归的结构出现,  

因为它们都会导致编译程序无法计算准确的存储空间需求.

 

                            也存放在RAM

                            由于这里的静态是指:固定的位置

                            然而将程序运行是一直存在的数据放入其中

                            所以将java中用static描述的类型放入其中,

                            你可以用static来标识一个对象特定元素是静态的,

但是对象将永远不可能放入静态存储区中

   常量存储

                            常量的值在编译的时候就被确定了                        

 

                            由于存放在ROM

                            所以常量值通常直接存放在程序代码的内部

                            这样做是安全的因为他们永远也不会改变

                            所以一般程序将代码和常量存放在其中

   RAM存储

                            由于存放完全存活与程序之外的数据

                            然而它可以不受任何程序的控制,在没有程序的时候也可以存在

                            流对象:     将对象转换成字节流,发送给另外一台机器

                            持久化对象: 将对象存放在磁盘上,但是它依然可以保存自己的状态

 

                            设计技巧为:将对象转换成可以存放在其他介子中的事物,在需要是可以恢复成常规的基于RAM的对象

-------转载请注明作者shiyongyin
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值