命令javac将.java文件编译成.class(字节码)文件。java运行字节码文件。JVM的类装载子系统将字节码文件加载到运行时数据区(类文件可在任何平台/ *** 作系统上由JVM(Java虚拟机)执行),jvm的字节码执行引擎执行内存区中的代码,将字节码文件翻译成机器可以识别执行的机器码。
java为什么能跨平台:java中针对不同 *** 作系统有不同的JVM(1V1)对应,字节码在JVM上执行,JVM将其翻译成对应 *** 作系统能识别执行的机器码。
JVM运行时数据区:
线程独占部分 随线程生命周期而创建和销毁。
线程共享部分 随虚拟机或GC而创建和销毁。
程序计数器:记录当前线程正在执行的字节码指令的地址值;
--注:若当前执行中线程挂起,程序计数器会当前线程运行到哪一步了,当这个线程重新运行时,接着之前的进度运行,而不是重头开始。
虚拟机栈:java方法执行的内存区域-------
:每执行一个线程,虚拟机栈就会分配一块空间来给它(也是栈)。一个线程中有多个方法,每调用一个方法就会在线程得到的虚拟机栈空间内分一块给方法使用(也是栈)--栈帧。
每个方法调用到执行完成,都有对应的栈帧在线程的虚拟机栈中入栈和出栈。
[方法a{局部变量表, *** 作数栈,动态连接,方法出口(方法返回地址)};
方法b{局部变量表, *** 作数栈,动态连接,方法出口(方法返回地址)}
...........]
局部变量表:存放方法参数和局部变量。
*** 作数栈:初始状态为空的桶式结构栈。JVM在其中执行局部变量的加减乘除等 *** 作。
动态链接::程序执行到方法的时候,会将这个方法的字节码,放在JVM的方法区中,动态链接中存放的就是方法区中该方法的内存地址。告诉这个方法栈帧他的字节码在方法区的哪里。
方法出口:1.正常退出:正常执行到方法的返回字节码指令。2.异常退出。
java虚拟机栈抛出的两个异常:
StackOverFlowError:虚拟机栈内存不能动态扩容时,线程请求栈深度大于规定的JVM虚拟机栈大小,抛出此异常。
OurOfMemoryError:虚拟机栈内存能动态扩容时,线程请求栈内存用完时,无法扩容,抛出此异常。
*** 作数栈和局部变量表交互:1.将常量13压入 *** 作栈,并保存在局部变量表slot_1处(x),
2.将常量14压入 *** 作栈,并保存在局部变量表slot_2处(y),
3.将局部变量表的slot_1压入 *** 作栈
4.将局部变量表的slot_2压入 *** 作栈
5.将两个数取出,在cpu中相加,在将和压回栈顶
6.将栈顶数据保存在局部变量表slot_3处
7.返回栈顶元素
本地方法栈: 本地方法栈为虚拟机使用到的Native方法服务,线程调用本地方法时需要本地方法栈为其分配空间。
--本地方法:被native修饰的方法,用来调用非java代码的接口。
保存在动态链接库中,即.dll(win系统)中。
Native关键字:
native关键字说明其修饰的方法是一个原生态方法,方法对应的实现不是在当前文件,而是 在用其他语言(如C和C++)实现的文件中。Java语言本身不能对 *** 作系统底层进行访问和 *** 作,但是可以通过JNI接口调用其他语言来实现对底层的访问。
用法:
编写带有native声明的方法的Java类(java文件)
使用javac命令编译编写的Java类(class文件)
使用javah -jni ****来生成后缀名为.h的头文件(.h的文件)
使用其他语言(C、C++)实现本地方法
将本地方法编写的文件生成动态链接库(dll文件)
堆内存:JVM启动时创建
存放对象(类实例对象和数组对象)
实例数据,对象的其他信息,Mark Word(存储对象哈希码,GC标志,GC年龄,同步锁等信息),Klass Pointy(指向存储类型元数据的指针),一些字节对齐补白的填充数据
{ 新生代-young 1/3占比 【Edan,s0,s1】 }Eden区填满时,触发young GC(minor GC)。
对象产生之初在新生代,步入暮年时进入老年代,但是老年代也接纳在新生代无法容纳的超大对象
{ 老年代-old 2/3占比}
方法区(元数据空间):存放常量(常量存放在运行时常量池),静态变量,类信息(类名,访问修饰符,字段描述,方法描述)
补充A:若静态变量是一个对象,那么对象存在堆中,方法区存放该对象在堆中的地址信息。
补充B: 1.方法区中的信息一般长期存在。
2. 对其进行回收的目的:回收常量池和类型的加载。
3.class文件常量池存放编译时期产生的字面量和符号引用,常量池在被类加载后存放到运行时常量池,切记jdk1.8以后String pool(字符串常量池)放在堆中(java Heap)
直接内存
直接内存不是虚拟机运行时数据区的一部分,也不是JVM规定的内存区,但在JVM的实际运行中会经常调用该区域,会抛出OOM。
JVM关闭
jvm关闭分3种情况
1.正常关闭,调用system.exit或最后一个非守护线程结束关闭JVM
2.异常关闭,抛出RunTimeException等异常,提前结束JVM
3.强制关闭,调用Runtime.halt
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)