第一部分 概念 Java中的内存由Java JVM 自己去管理的,他不像C++需要自己去释放。笼统地去讲,Java的内存分配为两个部分, 一个数数据堆,一个是栈。程序在运行的时候一般分配数据堆,把局部的临时的变量都放进去,生命周期和进程有关系。但 是如果程序员声明了static的变量,就直接在栈中运行,进程销毁了,不一定会销毁static变量。 另外为了保证Java内存不会溢出,Java有垃圾回收机制,System.gc()及垃圾收集机制。是指JVM用于释放那些不再 使用的对象所占用的内存。Java语言并不要求JVM有gc,也没有规定gc如何工作。垃圾手机的目的在与清除不再使用的对象。 gc通过确定对象是否被活动对象引用来确定是否收集该对象。 而其中,内存溢出就是你要求分配的Java虚拟机内存超出了系统能给你的。系统不能满足需求,于是产生溢出。 内存泄漏是指你向系统申请分配内存进行使用(NEW),可是使用完了以后却不归还(delete),结果你申请到的那块内 存你自己也不能在访问,该块已分配出来的内存也无法在使用,随着服务器内存的不断消耗,而无法使用的内存越来越多, 系统也不能在范围,该块已分配出来的内粗也无法再使用,随着服务器内存的不断消耗,而无法使用的内存越来越多,系统 也不能再次将它分配给需要的程序,产生泄露。一直下去,程序也逐渐无内存使用,就会溢出。 第二部分 原理 JAVA垃圾回收及对内存区划分 在Java虚拟机规范中,提及了如下几种类型的内存空间: ◇ 栈内存(Stack):每个线程私有的。 ◇ 堆内存(Heap):所有线程公用的。 ◇ 方法区(Method Area):有点像以前常说的“进程代码段”,这里面存放了每个加载类的反射信息、类函数的代码、 编译时常量等信息。 ◇ 原生方法栈(Native Method Stack):主要用于JNI中的原生代码,平时很少涉及。 而Java的使用的是堆内存,java堆是一个运行时数据区,类的实例(对象)从中分配空间。Java虚拟机(JVM)的堆中储存着 正在运行的应用程序所建立的所有对象,“垃圾回收”也是主要是和堆内存(Heap)有关。 垃圾回收的概念就是JAVA虚拟机(JVM)回收那些不再被引用的对象内存的过程。一般我们认为正在被引用的对象状态为 “alive”,而没有被应用或者取不到引用属性的对象状态为“dead”。垃圾回收是一个释放处于”dead”状态的对象的内存的 过程。而垃圾回收的规则和算法被动态的作用于应用运行当中,自动回收。 JVM的垃圾回收器采用的是一种分代(generational )回收策略,用较高的频率对年轻的对象(young generation)进行 扫描和回收,这种叫做minor collection,而对老对象(old generation)的检查回收频率要低很多,称为major collection。 这样就不需要每次GC都将内存中所有对象都检查一遍,这种策略有利于实时观察和回收。 一些对象被创建出来只是拥有短暂的生命周期,比如 iterators 和本地变量。另外一些对象被创建是拥有很长的生命周期,比 如 高持久化对象等。 垃圾回收器的分代策略是把内存区划分为几个代,然后为每个代分配一到多个内存区块。当其中一个代用完了分配给他的内 存后,JVM会在分配的内存区内执行一个局部的GC(也可以叫minor collection)操作,为了回收处于“dead”状态的对象所占 用的内存。局部GC通常要不Full GC要快很多。