java 程序运行的必要环境,java 之所以能够跨平台运行,完全是因为jvm底层做到多个平台兼容,所以java才能够在不同平台上进行运行(所以 个人觉得 java不牛 但是研究jvm这位挺牛的)
jvm基本组成
堆区(Java Heap): Java堆是被所有线程共享的一块内存区域,在虚拟机启动时创建。此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存(可以通过 通过-Xmx和-Xms控制 参数来指定大小),如果在堆中没有内存完成实例分配,并且堆也无法再扩展时,将会抛出OutOfMemoryError异常
java中 堆区 分为 新生代区域和老年代区域 其中新生代区域:老年代区域默认为1:2 (PS:比例可以修改)
其中新生代区域又分为Eden和Servivor1,Servivor2 比例为 8:1:1
栈(Java Virtual Machine Stacks)
也是线程私有的,它的生命周期与线程相同。虚拟机栈描述的是Java方法执行的内存模型:每个方法被执行的时候都会同时创建一个栈帧(Stack Frame)用于存储局部变量表、 *** 作栈、动态链接、方法出口等信息。每一个方法被调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。
栈区内包含栈帧 栈帧可以理解为执行程序中 每个执行方法所在的空间
其中包括但不限于
局部变量区域: 用来存放方法中创建的局部变量
*** 作数栈:记录当前进程执行到方法的什么位置
动态连接:指向本栈用引用其他栈地址连接信息
方法出口:本次执行完毕之后接下来程序需要处理的位置
本地方法栈
java中 存在一些方法 在调用java内部程序的时候 会有一些方法是 native 修饰的方法 这类方法称之为本地方法(这些方法的执行不是用java语言编写的,可能是C/C++/C#...),但是 当程序执行到这类方法时需要开辟空间 就要从本地方法栈中开辟
方法区(1.8之前 永久态/持久态 ;1.8之后又称元空间)
各个线程共享的内存区域,它用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。虽然Java虚拟机规范把方法区描述为堆的一个逻辑部分,但是它却有一个别名叫做Non-Heap(非堆),目的应该是与Java堆区分开来。
程序计数器(Program Counter Register)
程序计数器(Program Counter Register)是一块较小的内存空间,它的作用可以看做是当前线程所执行的字节码的行号指示器。在虚拟机的概念模型里(仅是概念模型,各种虚拟机可能会通过一些更高效的方式去实现),字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令,分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖这个计数器来完成
为了线程切换后能恢复到正确的执行位置,每条线程都需要有一个独立的程序计数器,各条线程之间的计数器互不影响,独立存储,我们称这类内存区域为“线程私有”的内存。此内存区域是唯一一个在Java虚拟机规范中没有规定任何OutOfMemoryError情况的区域。
学习连接
jvm系列(二):JVM内存结构
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)