1. Jvm的内存可以分为堆内存和非堆内存
1) 堆内存
Java 堆是被所有线程共享的一块内存区域,在虚拟机启动时创建。
Java所以实例和数组的内存均在此处分配。对象的对内存
java垃圾回收器回收。
堆内存由两部分组成:Eden+Survivor(Fromspace+Tospace)叫做Young Generation(年轻代)和Old Generation(年老代)
它们分别存放的内容如下:
Eden----所有新创建的对象
Survoivor(Fromspace+Tospace)---当Eden的内存空间不足时,会将Eden中依然存活的对象拷贝到Survoivor中的Fromspace或者Tospace中
Old Generation ---当一个Survivor区域满了的时候,会将该区域中的已历经过多次的依旧存活的对象放到Old Generation中
2) 非堆内存
主要包括PermanentGeneration , Jvm Stack(java虚拟机栈), Local Method Statck(本地方法栈)。
它们分别存放的内容如下:
PermanentGeneration ---存放了所加载的类的信息(名称、修饰符等)、类中的静态变量、类中定义为final类型的常量、类中的Field信息、类中的方法信息,
Jvm Stack(虚拟机栈)---虚拟机栈是线程私有的,每个线程的创建都会创建虚拟机栈,Jvm Stack中存放当前线程中的局部基本类型变量,部分的返回结果,StackFrame及非基本类型的对象指向堆上的地址。
Local MethodStatck(本地方法栈)---- JVM采用本地方法堆栈来支持native方法的执行,此区域用于存储每个native方法调用的状态。
2. Jvm的回收机制
Jvm采用分代回收(Generationcollection)的策略,用较高频率对年轻的对象(Young Generation)进行扫描和回收,这种叫做minor collection,而对老对象(Old Generation)的回收频率要低的多,称为major collection这样就不需要每次GC都将内存中所以的对象都检查一遍。
当创建一个java对象时,内存申请过程如下:
1) Jvm会试图为java对象在Eden中初始化一块内存区域
2) 当Eden空间足够时,内存申请结束。否则就到下一步
3) Jvm GC机制试图释放在Eden中所以不活跃的对象(这个回收比较频繁)如果释放后Eden空间仍然不足放入新对象,则试图将部分Eden中的存活的对象放入Survivor区中
4) Survivor区被用来作为Eden及Old Generation中间的交换区域,当Old Generation空间足够时,Survivor区的空间满时候,对象会被移动到Old Generation。
5) 当Old Generation区空间不够时,Jvm GC回收机制会在Old Generation进行完全的垃圾收集机制。
6) 完全垃圾收集后,若Survivor及Old Generation仍然无法存放从Eden复制过来的部分对象,导致Jvm无法在Eden为新对象创建内存区域,则出现“out of memory”错误。
3 Jvm GC回收算法
1)引用计数算法
为每一个对象添加一个计数器,计数器记录了对该对象的活跃引用的数量。如果计数器为0,则说明这个对象没有被任何变量所引用,即应该进行垃圾收集。
收集过程如下:
A减少被收集对象所引用的对象的计数器的值
B将其放入延时收集队列之中
2) 标记-清除收集器算法
收集过程分为2个阶段
A.首先停止所有工作,从根集遍历所有被引用的节点,然后进行标记,最后恢复所有工作
B.收集阶段会收集那些没有被标记的节点,然后返回空闲链表
标记-清除法的缺点在于
A.标记阶段暂停的时间可能很长,而整个堆在交换阶段又是可访问的,可能会导致被换页换出内存。
B.另外一个问题在于,不管你这个对象是不是可达的,即是不是垃圾,都要在清楚阶段被检查一遍,非常耗时.
C.标记清楚这两个动作会产生大量的内存碎片,于是当有大对象进行分配时,不需要触发一次垃圾回收动作
3) 拷贝收集器算法
该算法的提出是为了克服句柄的开销和解决堆碎片的垃回收。将内存分为两个区域(fromspace和tospace)。所有的对象分配内存都分配到fromspace。在清理非活动对象阶段,把所有标志为活动的对象,copy到tospace,之后清楚fromspace空间。然后互换fromsapce和tospace的身份。既原先的fromspace变成tosapce,原先的tospace变成fromspace。每次清理,重复上述过程。
4) 标记-整理收集器算法
标记整理收集器,通过融合了标记-清除收集器和拷贝收集器的优点,很好的解决了拷贝收集策略中,堆内存浪费严重的问题。
标记整理收集器分为2个阶段
1)标记阶段,这个阶段和标记-清除收集器的标记阶段相同
2)整理阶段,这个阶段将所有做了标记的活动对象整理到堆的底部