1. 内存分布区域

    1.寄存器:存储最快的区域,它不同于其它存储的地方——处理器内部。速度快,但寄存器的数量有限,会按需求进行内存分配,人为不可控制。

    2.堆栈(栈):速度仅次于寄存器,位于RAM(随机访问存储器)。因处理器支持栈指针(上下移动,向上释放空间,向下分配空间),所以项目在启动时需要知道堆栈中对象的生命周期,以便指针释放与分配空间。但这点限制了栈的灵活性,在堆栈区间内存储很多,尤其是引用,但从不存储new对象。

    3.堆:速度一般(反映出JAVA运行的速度没有c快),位于RAM(随机访问存储器),存储所有产生的对象(包含:new语句创建 与 非new语句创建)。处理器同样支持堆指针(只能简单的移动到未分配的区域),但不需要知道堆区域内对象的生命周期,这样加大了灵活性,但对内存的分配时间同样加长。堆的内存也可以细分为 new区 与 old区,在内存清理中起到不同的作用。

    4.常量存储:位于堆中的permanent区,简称”非堆”存储区,又称为“常量池“。会为每一个类型生成一个常量池,包括:基本类型,String 类型,其他类型,方法名称等。内部是通过HashSet实现的。

    5.代码区:存放程序中方法的二进制代码,而且是多个对象共享一个代码空间。

    6. 数据区:用来存放static 定义的静态成员。


2.清理机制:垃圾回收器回收堆中new创建的对象。

    清理的是堆,不是栈。栈为超出作用域,及时清理。

    堆清理机制: java虚拟机会进行检测,如果所有对象都很稳定,垃圾回收器的效率降低的话,就会切换到“标记-清扫”方式:同样Java虚拟机会跟踪“标记-清扫”的效果,要是堆空间出现很多碎片就会切换到“停止-复制”方式。这方式为“自适应技术”,是大多数虚拟机的主流机制。目的是为加快效率。当然尽管如此,速度只是不慢而已。

    标记-清扫:从栈与静态区追溯(遍历所有的引用)到对应对象,将追溯到的对象进行标记,并将没有标记的对象全部删除(回收器先进行标记,然后调用finalize方法,可删除非构造器产生的对象)。清除后的空间是不连续的。

    停止-复制:停止系统的运行,从栈与静态区开始追溯到对应的对象,将追溯到的对象从原来的old区复制到new区。在new区是连续排列的,通过遍历对象将所有引用的地址更新。old区中剩余全部清除,成为new区,如此循环。

 补充点:
    1.活对象:存在引用所指向的对象。

    2. 虚拟机清理技术还有“引用计数技术”,但慢,不常用。

    3. 并不是所有的对象都是通过 构造器产生的。

    4.堆区是可以人为划分的。

    5.停止-复制中用到了 goto 函数

    6.JVM 的惰性评估(惰性加载)是一种提高效率的方式