Java内存结构和Java垃圾回收机制,
Java内存结构和Java垃圾回收机制,
一、Java内存结构
Java内存结构主要有三大块:堆,方法区(持久代)和栈。
1. 堆内存是JVM中最大的一块有年轻代和年老代组成,而年轻代又被分为三部分,即Eden空间,Survivor1(From Survivor)空间,Survivor2(To Survivor)空间,默认情况下三者按照8:1:1的比例来分配。 对象被new之后一般都被放置在年轻代,在年轻代中经历了N次垃圾回收后仍然能够存活的对象,将从年轻代过渡到年老代的缓冲地带。
对于大多数应用,Java堆是Java虚拟机所管理的内存中的最大的一块。Java堆是被所有线程所共享的一块内存区域,在虚拟机启动时创建,只要存放类对象的实例信息。
控制参数:-Xms设置堆的最小空间值,-Xmx设置堆的最大空间值。
-XX:NewSize设置新生最小空间值,-XX:MaxNewSize设置新生代最大空间值。
2. 方法区与Java堆一样,是各个线程所共享的内存区域,它用于存储已经被虚拟机加载的类信息,静态变量,常量等数据。在HotSpot虚拟机上使用时,开发者也将方法区称之为”持久代“,但是二者并不是等价的,仅仅是因为HotSpot虚拟机的设计团队选择把GC分代收集扩展至方法区,实际上也就是说是使用永久代来实现方法区而已。
控制参数:-XX:PermSize设置永久代最小空间值、-XX:MaxPermSize设置永久代最大空间值
3.栈又分为虚拟机栈和本地方法栈 ,主要用于方法的执行。
Java虚拟机栈是线程所私有的,它的生命周期与线程相同。虚拟机栈描述的是Java方法执行的内存模型:每个方法被执行的时候都会同时创建一个栈帧用于存储局部变量表、操作数栈、帧数据区等信息。每一个方法被调用直至执行完成的过程中,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。
本地方法栈与虚拟机栈所发挥的作用是类似的,其区别只不过是虚拟机栈为虚拟机执行Java方法(也就是字节码)服务,而本地方法栈则是为虚拟机使用到的Native方法服务。在我们常用的虚拟机Sun公司的HotSpot虚拟机,直接是把本地方法栈和虚拟机栈合二为一。
,
二、Java垃圾回收机制
1.如何判断一个对象是垃圾对象?
①引用计数法:当计数器为0时就说明该对象是不可能再被使用的对象。
②跟可达性分析法:法①实现简单,而且效率较高,但是它无法解决循环引用的问题,所以在Java中我们采取”跟可达性分析法“。该方法的基本思想是通过一系列”GC Roots"对象作为起点,从这些点开始依次向下搜索,搜索所走过的路径称为引用链。当一个对象到达GC Roots没有任何引用链相连时,就证明此对象是不可用的、可以被回收的。如:
1
Object aobj = new Object ( ) ;
2 Object bobj = new Object ( ) ;
3 Object cobj = new Object ( ) ;
4 System.out.println(aobj+"====== "+bobj+"===== "+cobj);
5 aobj = bobj;
6 aobj = cobj;
7 cobj = null;
8 aobj = null;
9 System.out.println(aobj+"====== "+bobj+"===== "+cobj);
第7,8行将会导致aobj和bobj称为回收对象
2.典型的垃圾回收算法
①.复制算法:两个区域A和B,初始对象在A,继续存活的对象将会被转移到B,这是新生代最常用的算法。新生代被划分为一块较大的Eden区域和两块较小的Survivor空间,每次使用Eden空间和其中一块Survivor空间,当进行内存回收时,将Eden空间和Survivor空间中还存活的对象复制到另外一块Survivor空间,然后清理掉Eden空间和刚才使用的Survivor空间。
这种算法虽然简单,但是却对内存空间的使用付出代价更大,因为能够使用的内存只能缩减为原来的一半。
②.标记-清除算法:这是最基础的垃圾回收算法,标记-清除算法顾名思义主要分为两个阶段:标记阶段和清除阶段。标记阶段的任务是标记出所有需要被回收的对象,清除阶段就是回收所有被标记的对象所占用的空间。标记-清除算法实现起来非常容易,但是有一个严重的问题就是容易产生内存碎片,碎片太多可能会导致后续过程中需要为大对象分配空间时无法找到足够的空间而提前出发新的一次垃圾回收动作。
③.标记-整理算法:为解决复制算法的缺陷,充分利用到内存空间,又提出了标记-整理算法。该算法前期也是先将所有需要被回收的对象先标记出来,但是在标记完成之后,它不是直接清理可回收对象,而是将存活对象都向一端移动,然后清理掉端边界以外的内存。
相关文章
- 暂无相关文章
用户点评