﻿1、Java 程序运行时的内存分配策略有三种：

    (1) 静态分配
    (2) 栈式分配
    (3) 堆式分配

2、对应的三种存储策略使用的内存空间如下：

    (1) 静态存储区(也称方法区)
            主要存放静态数据、全局 static 数据和常量。这块内存在程序编译时就已经分配好，
        并且在程序整个运行期间都存在。

    (2) 栈区
            当方法被执行时，方法体内的局部变量都在栈上创建，并在方法执行结束时这些局部变量
        所持有的内存将会自动被释放。因为栈内存分配运算内置于处理器的指令集中，效率很高，
        但是分配的内存容量有限。

    (3) 堆区
            又称动态内存分配，通常就是指在程序运行时直接 new 出来的内存。这部分内存在不使
        用时将会由 Java 垃圾回收器来负责回收。

    (4) 栈与堆的区别：
    		    在方法体内定义的（局部变量）一些基本类型的变量和对象的引用变量都是在方法的栈内存
    		中分配的。当在一段方法块中定义一个变量时，Java 就会在栈中为该变量分配内存空间，当超过
    		该变量的作用域后，该变量也就无效了，分配给它的内存空间也将被释放掉，该内存空间可以被
    		重新使用。

    		    堆内存用来存放所有由 new 创建的对象（包括该对象其中的所有成员变量）和数组。在堆中分
    		配的内存，将由 Java 垃圾回收器来自动管理。在堆中产生了一个数组或者对象后，还可以在栈
    		中定义一个特殊的变量，这个变量的取值等于数组或者对象在堆内存中的首地址，这个特殊的变
    		量就是我们上面说的引用变量。我们可以通过这个引用变量来访问堆中的对象或者数组。

	(5) 结论：
    		    局部变量的基本数据类型和引用存储于栈中，引用的对象实体存储于堆中。—— 因为它们属于
    		方法中的变量，生命周期随方法而结束。
    		成员变量全部存储与堆中（包括基本数据类型，引用和引用的对象实体）—— 因为它们属于
    		类，类对象终究是要被 new 出来使用的。

3、Java 是如何管理内存

            Java 的内存管理就是对象的分配和释放问题。在 Java 中，程序员需要通过关键字 new 为
        每个对象申请内存空间 (基本类型除外)，所有的对象都在堆 (Heap)中分配空间。另外，对象的
        释放是由 GC 决定和执行的。在 Java 中，内存的分配是由程序完成的，而内存的释放是由 GC
        完成的，这种收支两条线的方法确实简化了程序员的工作。但同时，它也加重了JVM的工作。
        这也是 Java 程序运行速度较慢的原因之一。因为，GC 为了能够正确释放对象，GC 必须监控
        每一个对象的运行状态，包括对象的申请、引用、被引用、赋值等，GC 都需要进行监控。监视
        对象状态是为了更加准确地、及时地释放对象，而释放对象的根本原则就是该对象不再被引用。

4、什么是 Java 中的内存泄露
    		    在 Java 中，内存泄漏就是存在一些被分配的对象，这些对象有下面两个特点，首先，这些对象是
    		可达的，即在有向图中，存在通路可以与其相连；其次，这些对象是无用的，即程序以后不会再
    		使用这些对象。如果对象满足这两个条件，这些对象就可以判定为 Java 中的内存泄漏，这些对象
    		不会被 GC 所回收，然而它却占用内存。
