JVM内存结构

  • 前言

  JAVA GC(Garbage Collection,垃圾回收)机制是区别C++的一个重要特征,c++的开发人员需要自己管理每一个对象的创建和销毁.而对于java的开发人员来说,他们不需要了解对象的创建和销毁,因为jvm已经帮我们把这件事-"垃圾回收"代劳了.但这并不意味着我们不用去理解GC机制的原理,因为如果不了解其原理,可能会引发内存泄漏、频繁GC导致应用卡顿,甚至出现OOM等问题,因此我们需要深入理解其原理,才能编写出高性能的应用程序,解决性能瓶颈。

       想要理解GC的原理,我们必须先理解JVM内存管理机制,因为这样我们才能知道回收哪些对象、什么时候回收以及怎么回收。

  • JVM内存管理

JVM把它所管理的内存划分为以下5个不同的数据区域

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

 

  • 序计数器(Program Counter Register)

程序计数器是一块较小的内存空间,它可以看作是当前线程所执行的字节码的行号指示器.程序中的分支,循环,跳转,异常处理,线程恢复等基础功能都需要依赖这个计数器来完成的.

每一条线程都有一个独立的程序计算器,各个线程之间的计数器互不影响,独立存储,所以程序计数器是"线程私有"的.

如果线程执行的是一个java方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址;如果正在执行的是Native方法,这个计数器则为空.并且该内存区域是唯一一个不会出现OutOfMemiryError异常的区域。

  • 虚拟机栈(VM Stack

每个线程都有一个虚拟机栈,它的生命周期与线程相同,也是线程私有的。

每一方法在执行的时候都会在虚拟机栈中压入一个栈帧(Stack Frame),它用于存储局部变量表,操作数栈,动态链接,方法出口等信息.而当方法结束时,其对应的栈帧就会从虚拟机栈中出栈.

在虚拟机栈中有两种异常情况:

StackOverflowError异常:当现场请求的栈深度大于虚拟机所允许的深度,将抛出StackOverflowError异常.一般该异常会出现在虚拟机栈的长度是固定的时候,而现在大部分的虚拟机栈都是可以动态扩展的.

OutOfMemoryError异常:如果虚拟机栈可以动态扩展,并且扩展时无法申请到足够的内存就会抛出OutOfMemoryError异常

  • 本地方法栈

本地方法栈的功能和虚拟机栈的功能差不多,两者不同之处在与:虚拟机栈执行的是java方法(也就是字节码),而本地方法栈执行的是Native方法(本地方法).

在虚拟机规范并没强制规定本地方法栈中使用的语言,使用方式与数据结构.因此在有的虚拟机中(如hotspot虚拟)会把本地方法栈和虚拟机栈合二为一.

本地方法栈也会抛出StackOverflowError和OutOfMemoryError异常

  • 堆区(Heap

java堆是java虚拟机所管理的内存中最大的一块.同时它并不是线程私有的,它被所有线程所共享.堆区的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存.

堆区是垃圾收集器管理的注意区域,因此也被称为"GC"堆

 

  • 方法区(Method Area

方法区用于存储已被虚拟机加载的类信息,常量,静态变量,即使编译器编译后的代码等数据.它是非线程私有的区域,能被各个线程所共享.当方法区超过它允许的大小时,就会抛出OutOfMemory:PermGen Space异常。

在Hotspot虚拟机中,这块区域对应持久代(Permanent Generation),一般来说,方法区上执行GC的情况很少,因此方法区被称为持久代的原因之一,但这并不代表方法区上完全没有GC,其上的GC主要针对常量池的回收和已加载类的卸载。在方法区上进行GC,条件相当苛刻而且困难。

 运行时常量池(Runtime Constant Pool)是方法区的一部分,用于存储编译器生成的常量和引用。一般来说,常量的分配在编译时就能确定,但也不全是,也可以存储在运行时期产生的常量。比如String类的intern()方法,作用是String类维护了一个常量池,如果调用的字符”hello”已经在常量池中,则直接返回常量池中的地址,否则新建一个常量加入池中,并返回地址。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值