java程序的执行流程

程序运行流程图:

java程序的执行流程_第1张图片

如上图所示,首先Java源代码文件(.java后缀)会被Java编译器编译为字节码文件(.class后缀),然后由JVM中的类加载器加载各个类的字节码文件,加载完毕之后,交由JVM执行引擎执行。在整个程序执行过程中,JVM会用一段空间来存储程序执行期间需要用到的数据和相关信息,这段空间一般被称作为Runtime Data Area(运行时数据区),也就是我们常说的JVM内存。因此,在Java中我们常常说到的内存管理就是针对这段空间进行管理(如何分配和回收内存空间)。

运行时数据区图:

java程序的执行流程_第2张图片

Java总内存:
总内存=堆内存(Xmx)+方法区内存(MaxPermSize)+栈内存(Xss)*线程数+直接内存(MaxDirectMemorySize,堆外)+虚拟机内存

堆内存

Java堆(Java Heap)是被所有线程共享的一块区域,所有的对象实例以及数组都要在堆上分配。

程序计数器

程序计数器是一块较小的内存空间,它可以看作是当前线程所执行的字节码的行号指示器。在虚拟机的概念模型里,字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令,分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖这个计数器来完成。
Java虚拟机的多线程就是通过线程轮流切换并分配处理器执行时间的方式来实现的,任何一个确定的时刻,一个处理器只会执行一条线程中的指令。所以为了线程切换后能恢复到正确的执行位置,每条线程都需要有一个独立的程序计数器。每个线程都有自己单独的程序计数器,互不影响这个属于“线程私有”的内存。

Java虚拟机栈(执行内存模型)

Java虚拟机栈也是线程私有的,它的生命周期与线程相同。虚拟机栈描述的是Java方法执行的内存模型,每个方法被执行的时候都会同时创建一个栈帧(Stack Frame)用于存储局部变量表、操作栈、动态链接、方法出口等信息。
当线程调用Java方法时,虚拟机压入一个新的栈帧到对应线程的虚拟机栈中;当方法返回时,这个栈帧就被从栈中弹出并抛弃。
局部变量表所需的内存空间在编译期间完成分配,当进入一个方法时,这个方法需要在帧中分配多大的局部变量空间是完全确定的,在方法运行期间不会改变局部变量表的大小。

方法区

方法区是各个线程共享的内存区域,它用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。
这个区域的内存回收目标主要是针对常量池和对类型的卸载。
当方法区无法满足内存分配需求时,将抛出OutOfMemoryError异常。

你可能感兴趣的:(后端菜鸟)