黑马程序员技术交流社区

标题: 关于java内存的知识点总结 [打印本页]

作者: 人在旅途~东营    时间: 2015-5-29 23:22
标题: 关于java内存的知识点总结
Java内存结构对于我们这些初学者来说,学习起来比较困难,正好忙着学习总结,顺便跟大家分享下。
1. Java有几种存储区域?
寄存器
     --在CPU内部,开发人员不能通过代码来控制寄存器的分配,有编译器来管理。

    --在windows下,栈是向底地址扩展的数据结构,是一块连续的内存的区域,即栈顶的地址和栈的最大容量是系统预先定好的。
     --优点:由系统自动分配,速度较快。
     --缺点:不够灵活,程序员无法控制。
     --存放基本数据类型、开发过程中就创建的对象(而不是运行过程中)。

     --是向高地址扩展的数据结构,是不连续的内存区域。
     --在堆中,没有堆栈指针,为此也就无法直接从处理器那边获得支持。
     --堆的好处是有很大的灵活性。如Java编译器不需要知道从堆里需要分配多少存储区域,也不必知道存储的数据在堆里会存活多长时间。
静态存储区域与常量存储区域
     --静态存储区用来存放static类型的变量
     --常量存储区用来存放常量类型(final)类型的值,一般在只读存储器中。
非RAM存储
     --如流对象,是要发送到另一台机器上。
     --持久化的对象,存放在磁盘上。

2. Java内存分配
     --基础数据类型直接在栈空间分配。
     --方法的形式参数,直接在栈空间分配,当方法调用完成后从栈空间回收。
     --引用数据类型,需要用new来创建,既在栈空间分配一个地址空间,又在堆空间分配对象的类变量。
     --方法的引用参数,在栈空间分配一个地址空间,并指向堆空间的对象区,当方法调用完后从栈空间回收。
     --局部变量new出来时,在栈空间和堆空间中分配空间,当局部变量生命周期结束后,栈空间立即被回收,堆空间区域等待GC回收。
     --方法调用时传入的literal参数,先在栈空间分配,在方法调用完成后从栈空间释放。
     --字符串常量在DATA区域分配,this在对空间分配
     --数组既在栈空间分配数组名称,又在堆空间分配数组实际的大小

3. Java内存模型
     Java虚拟机将其管辖的内存大致分三个逻辑部分:方法区、栈、堆。
     --方法区是静态分配的,编译器将变量绑定在某个存储位置上,而且这些绑定不会再运行时改变。
          常数池,源代码中的命名常量、string常量和static变量保存在方法区。
     --Java Stack是一个逻辑概念,特点是后进先出。一个栈的空间可能是连续的,也可能是不连续的。
          最典型的stack应用是方法的调用,java虚拟机每调用一次方法就创建一个方法帧(frame),退出时则对应的方法帧被弹出。栈中存储的数据也是运行时确定的。(弹匣)
     --Java堆分配 意味着以随意的顺序,在运行时进行存储空间分配和收回的内存管理模型。
          堆中存储的数据常常是大小、数量和生命期在编译时无法确定的。java对象的内存总是在heao中分配。


二、Java垃圾回收机制(GC)
1. JVM运行环境中垃圾对象的定义
     一个对象创建后被放置在JVM的堆内存中,当永远不再引用这个对象时,它将被JVM在堆内存中回收。或当对象在JVM运行空间中无法通过根集合(root set)到达时,这个对象就被称为垃圾对象。

2. 堆内存
     在JVM启动时被创建;堆内存中所存储的对象可以被JVM自动回收,不能通过其他外部手段回收。
     堆内存可分为两个区域:新对象区和老对象区
     --新对象区可分为三个小区:Eden区、From区、To区

3. JVM中对象的生命周期
     创建阶段
     --为对象分配存储空间
     --开始构造对象
     --递归调用其超类的构造方法
     --进行对象实例初始化与变量初始化
     --执行构造方法体
     
     应用阶段
     --特征:系统至少维护着对象的一个强引用;所有对该对象引用强引用(除非显示声明为其他引用)
     
     不可视阶段
     --如果一个对象已使用完,并且在其可视区域不再使用,应该主动将其设置为null,即obj=null;这样可以帮助JVM及时发现这个垃圾对象,并且可以及时地回收该对象所占用的系统资源。
         
4. finalize
     finalize()方法常称之为终止器
     protected void finalize(){
           // finalization code here
     }
     对象即将被销毁时,有时需要做一些善后工作,可以把这些操作写在finalize()方法里。
     Java终止器却是在对象被销毁时调用。一旦垃圾收集器准备好释放无用对象占用的存储空间,它首先调用那些对象的finalize()方法,然后才真正回收对象的内存。而被丢弃的对象何时被销毁,应用是无法获知的。大多数场合,被丢弃对象在应用终止或仍未销毁。到程序结束的时候,并非所有收尾模块都会得到调用。


作者: 黑马生涯    时间: 2015-5-29 23:28
不错,统计的不错,占一个。
作者: 人在旅途~东营    时间: 2015-5-30 09:46
为什么发的帖子没人看啊,每次发的帖子都很认真啊:dizzy:
作者: 王建伟    时间: 2015-5-30 09:50
很吊的总结啊,学习了
作者: kmlitheima    时间: 2015-5-30 10:42
这个总结是真经典!




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2