JVM 温习一遍

JVM是 java virtual machine的简称,开始的时候主要是针对java语言而生的虚拟机,JVM模型主要是指在运行时jvm实例中内存使用的结构。

简单的说明一下JVM实例,一个java程序启动就会对应创建一个JVM实例,main函数是JVM实例运行的起点。一般来说,每个应用都运行都独享一个独立的JVM实例与操作系统进程。

JVM实例产生时,各区域也就随之产生。

JVM 温习一遍

这张图画的不错,我就直接拿过来了,运行时的JVM按照内存的使用形式可以分为线程共享区与线程独占区,顾名思义,线程共享区内存被所有线程共享,而线程独占区是线程私有的,每个线程拥有独立的此种内存空间。

方法区(Method Area)存储已被虚拟机加载的类信息(类的元数据)、常量、静态变量、即时编译后的代码等数据,方法区在逻辑上属于堆(heap)的一部分,但为了与堆进行区分,也把方法区叫做“非堆”。我们在使用的时候可以通过JVM的参数调整方法区的初始大小与限制,在限制范围内,JVM可以根据需要动态调整方法区的大小。

堆(Heap)java对象的存放处,是JVM管理内存区域中的最大的一块,也是垃圾收集器管理的最主要区域。java堆是逻辑上连续的内存区域,但在物理分布上可能是分散的。java堆的初始化大小及限制也可以通过JVM参数指定。

有一点需要注意的是,现在使用最广的虚拟机是HotSpot虚拟机,一般的堆从GC机制角度来说,分为新生代与老年代,而在HotSpot虚拟机中多了一个永久代的概念,“永久代”只是HotSpot的实现机制,在JVM规范中是没有这个概念的。HotSpot使用“永久代”来实现的方法区,所以用惯了SunJdk或OpenJdk的我们习惯将方法区也叫做“永久代”,但准确的说这样叫是不准确的。“永久代”在JDK1.8中被移除,被“MetaSpace”所替代。

虚拟机栈(Java Virtual Machine Stack)是线程私有的,每个线程都有独立的虚拟机栈。栈中包含多个栈帧,线程执行时每调用一个方法时就会往栈中创建并压入一个栈帧,栈帧存储局部变量表、操作栈、动态链接、方法出口等信息,法从调用到返回对应栈帧从入栈到出栈。栈是后入先出(LIFO),线程运行时,只有处于栈顶的栈帧才是有效的,称为当前栈帧,与这个栈帧相关联的方法称为当前方法,当前活动帧栈始终是虚拟机栈的栈顶元素。虚拟机栈的内存大小可以是固定的,也可以动态分配的。多线程时,固定大小的虚拟机栈内存耗尽时会出现栈溢出异常,动态分配的虚拟机栈内存耗尽会出现内存溢出异常。单线程时,则只会出现栈溢出异常。

这里需要特别说明一下局部变量表,也就是“栈内存”,它存放着编译时就已经明确的基本变量及引用类型,它所占用的空间在编译时就已经确定。即在运行时,它所分配的空间是明确的,在运行过程中不会改变。

本地方法栈(Native Method Stack)与虚拟机栈类似,但他的使用对象是native方法。

程序计数器(Program Counter Register)保存着当前线程执行的虚拟机字节码指令的内存地址,JVM的多线程是通过CPU切换计算任务并分配时间片完成的,在同一时刻一个CPU只能执行某一线程的任务,这就需要程序计数器记录上一时间分片线程所执行到的位置,以保证计算任务的顺利执行。


我们的目标:让生活更加美好!


分享到:


相關文章: