Java中的内存管理机制

Java内存的划分

  1. java把内存分为两种
  • 栈内存
  • 堆内存
  1. 栈内存
  • 在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配,当在一段代码中定义一个变量时,java就会在栈中为这个变量分配内存空间,当超过变量的作用域后,java会自动释放掉为该变量分配的内存,该内存空间可以立即另作他用
  1. 堆内存
  • 堆内存用于存放由new创建的对象和数组,在堆中分配内存,由GC来自动回收内存。在堆中产生了一个数组或对象后,还可以在栈中定义一个特殊的变量,这个变量的取值等于数组或者对象在堆内存中的首地址,在栈中的这个特殊的变量就变成了数组或对象的引用变量,以后可以在程序中使用栈内存的引用变量来访问堆中的数组或对象,引用变量相当于为数组或对象起的一个名字,或者代号
  1. 释放时机
  • 引用变量是普通变量,定义时在栈中分配内存,引用变量在程序运行到作用域外释放
  • 数组或对象本身在堆中分配,即使程序运行到使用new产生数组和对象的语句所在地代码之外,数组和对象本身占用的堆内存也不会释放,数组和对象在没有引用变量指向它的时候,才能变成垃圾,不能再被使用,但是仍然占着内存,在随后的一个不确定的时间被垃圾回收器释放掉--这也是java比较占内存的主要原因
  1. java中的“指针”
  • 首先明确:java不谈指针
  • 栈中的变量指向堆内存的变量--这就是java中的指针

内存分配策略

  1. 静态存储分配
  • 是指在编译时期就能确定每个数据目标在运行时刻的存储空间需求,因而在编译时就可以给他们分配固定的内存空间
  • 静态分配策略要求程序代码中不许有可变数据结构的存在,也不允许有嵌套或者递归的结构出现(因为会导致编译程序无法计算准确的存储空间)
  1. 栈式存储分配
  • 也称动态存储分配,是由一个类似于堆栈的运行栈来实现的,和静态存储分配相反,在栈式存储方案中,程序对数据区的需求在编译时是完全未知的,只有到运行的时候才能够知道,但规定在运行中进入一个程序模块时,必须知道该程序模块所需的数据区大小才能够为其分配内存。
  1. 堆式存储分配
  • 专门负责在编译时或运行时模块入口处都无法确定存储要求的数据结构的内存分配
  • 比如可变长字符串和对象实例
  • 堆由大片的可利用块或空闲块组成,堆中的内存可以按照任意顺序分配和释放

通俗易懂的解释

术语

解释

特点

优点

缺点


存放对象

应用程序在运行的时候请求操作系统分配给自己内存,由于操作系统管理的内存分配,所以在分配和销毁时都要占用时间,因此用堆的效率非常低,但是灵活

大小可以不固定

速度慢


执行程序

运行函数的时候,局部变量、形式参数,都是从栈中分配内存空间的,退出函数的时候,修改栈指针就可以把栈中的内容销毁,因此速度非常的快,但是分配的大小是确定的,不变的

存取速度快,仅次于寄存器

大小固定

记住以下箴言

  • java程序的运行就是通过堆栈的操作来完成的;
  • 堆栈以帧为单位保存线程的状态;
  • JVM对堆栈只进行两种操作:以帧为单位的压栈和出栈操作
  • 当前方法使用的帧称为当前帧
  • java自动管理堆和栈,程序猿不能直接的设置栈或堆