深入理解java GC 机制

一、前言

Java的GC(垃圾回收)机制是区别C++的一个重要特征。C++需要开发者在代码中实现垃圾回收逻辑,但在Java中,JVM帮开发者代劳了。我们只有理解了GC机制,才能编写出高性能的应用。要想理解GC,就要先理解JVM内存管理机制。这样才能知道回收哪些对象,什么时候回收以及怎么回收

二、JVM

根据JVM规范,JVM把内存划分成了如下几个区域:

1.方法区(Method Area)
2.堆区(Heap)
3.虚拟机栈(VM Stack)
4.本地方法栈(Native Method Stack)
5.程序计数器(Program Counter Register)

其中,方法区和堆区所有线程共享。
静态变量 + 常量 + 类信息(构造方法/接口定义) + 运行时常量池存放在 方法区 中
实例变量 存放在 堆内存 中

2.1 方法区(Method Area)

方法区存放了要加载的类的信息(如类名、修饰符等)、静态变量、构造函数、final定义的常量、类中的字段和方法等信息。方法区是全局共享的,在一定条件下也会被GC。当方法区超过它允许的大小时,就会抛出OutOfMemory:PermGen Space异常。
在Hotspot虚拟机中,这块区域对应持久代(Permanent Generation),一般来说,方法区上执行GC的情况很少,因此方法区被称为持久代的原因之一,但这并不代表方法区上完全没有GC,其上的GC主要针对常量池的回收和已加载类的卸载。在方法区上进行GC,条件相当苛刻而且困难。
运行时常量池(Runtime Constant Pool)是方法区的一部分,用于存储编译器生成的常量和引用。一般来说,常量的分配在编译时就能确定,但也不全是,也可以存储在运行时期产生的常量。比如String类的intern()方法,作用是String类维护了一个常量池,如果调用的字符"hello"已经在常量池中,则直接返回常量池中的地址,否则新建一个常量加入池中,并返回地址。

2.2 堆区(Heap)

堆区是GC最频繁的,也是理解GC机制最重要的区域。堆区由所有线程共享,在虚拟机启动时创建。堆区主要用于存放对象实例及数组,所有new出来的对象都存储在该区域。

2.3 虚拟机栈(VM Stack)

虚拟机栈占用的是操作系统内存,每个线程对应一个虚拟机栈,它是线程私有的,生命周期和线程一样,每个方法被执行时产生一个栈帧(Statck Frame),栈帧用于存储局部变量表、动态链接、操作数和方法出口等信息,当方法被调用时,栈帧入栈,当方法调用结束时,栈帧出栈。
局部变量表中存储着方法相关的局部变量,包括各种基本数据类型及对象的引用地址等,因此他有个特点:内存空间可以在编译期间就确定,运行时不再改变。
虚拟机栈定义了两种异常类型:StackOverFlowError(栈溢出)和OutOfMemoryError&#

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值