JVM内存分区和垃圾回收GC机制

JVM内存分区

JVM(Java virtual machine),即Java虚拟机,它的厉害之处在于平台无关性,“一处编写,到处运行”。JVM通过执行目标字节码(.class),解释在不同平台上的机器运行,所以在具体的平台上并不产生直接依赖。

JVM的内存空间主要有5种分区情况:
1. 线程计数器:一块较小的内存空间,每个线程都有自己的线程计数器,用于完成不同线程上下文切换,如果调用的是本地方法,pc寄存器不存储任何信息。
2. 堆区(Heap):所有线程共享堆空间,主要存放对象实例与数组,new创建的对象内存都在此分配,因为线程共享,所以需要加锁造成new的开销比较大。
3. 栈区(stack):栈与线程计数器一样,都是线程独有,栈的生命周期与线程的生命周期同步。每一次方法执行时就会同时创建一个栈帧,用于存储局部变量和操作数栈。每一个方法调用到执行完毕就对应着栈桢在栈区入栈到出栈的过程。
4. 本地方法栈:本地方法执行的时候,进入本地方法栈。
5. 方法区:和堆区一样,都是线程共享。存放JVM加载的类型信息,如类型基本信息,常量,方法表等等。

GC机制

GC是java中的垃圾收集器,也是不同于C++的一个地方。C++编程人员容易因为忘记或者错误地回收内存而造成程序崩溃,而Java通过GC机制监测对象是否超过作用域,从而达到自动回收内存的目的。

GC的常用算法

GC的依据就是监测对象的“可达”或“不可达”状态,但为了让GC适配不同的平台,所以GC并没有对如何进行回收作十分严格的规定,不同的实现者有不同的算法。主要有以及下三种:
1. 引用计数法。简单但速度很慢。缺陷是:不能处理循环引用的情况。
2. 停止-复制(stop and copy)。效率低,需要的空间大,优点,不会产生碎片。
3. 标记 - 清除算法 (mark and sweep)。速度较快,占用空间少,标记清除后会产生大量的碎片。
综述:新生代基本采用复制算法,老年代采用标记整理算法。cms采用标记清理。

GC分代


1. Young Generation
* Eden Space (any instance enters the runtime memory area through eden)
* S0 Survivor Space (older instances moved from eden to S0)
* S1 Survivor Space (older instances moved from S0 to S1)
2. Old Generation (instances promoted from S1 to tenured)
3. Permanent Generation (contains meta information like class, method detail)
总体来说,就是新生的对象总是放在Young Generation的eden空间里,而S0和S1存放的是垃圾回收后剩下存活的对象,而Old Generation则存放一些生命周期上的对象。Young Generation在垃圾回收时,对象的存储顺序是优先级是S0—->S1—->Old Generation,此时Young Generation利用的是上面提到的(stop-copy)算法,而Old Generation里的回收算法则是 (mark and sweep)算法。

另外还有一种是增量式GC(Incremental GC),这种GC在JVM中通常是由一个或一组进程来实现的,它本身也和用户程序一样占用heap空间,运行时也占用CPU。

HotSpot JVM增量式GC的实现是采用Train GC算法,它的基本想法就是:将堆中的所有对象按照创建和使用情况进行分组(分层),将使用频繁高和具有相关性的对象放在一队中,随着程序的运行,不断对组进行调整。当GC运行时,它总是先回收最老的(最近很少访问的)的对象,如果整组都为可回收对象,GC将整组回收。这样,每次GC运行只回收一定比例的不可达对象,保证程序的顺畅运行。

两个最基本的java回收算法:复制算法和标记清理算法
复制算法:两个区域A和B,初始对象在A,继续存活的对象被转移到B。此为新生代最常用的算法
标记清理:一块区域,标记要回收的对象,然后回收,一定会出现碎片,那么引出标记-整理算法:多了碎片整理,整理出更大的内存放更大的对象

JVM类加载器

一个jvm中默认的classloader有三种类型,Bootstrap ClassLoader、Extension ClassLoader、App ClassLoader,分别各司其职:
Bootstrap ClassLoader 负责加载java基础类,主要是 %JRE_HOME/lib/ 目录下的rt.jar、resources.jar、charsets.jar和class等
Extension ClassLoader 负责加载java扩展类,主要是 %JRE_HOME/lib/ext 目录下的jar和class
App ClassLoader 负责加载当前java应用的classpath中的所有类。
利用双亲委托模型来进行加载
JVM在判定两个class是否相同时,不仅要判断两个类名是否相同,而且要判断是否由同一个类加载器实例加载的

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值