目录
java编译相关知识
Java文件编译过程
大家都知道计算机只知道0100101010101这种二进制,那么我们的代码是怎么运行的呢??当然和编译有关,当我们写完aaa.java文件之后,我们需要通过javac来进行编译,编译成.class文件。因为JVM只认识.class文件。
java的可跨平台性
大家都知道java有一个很强大的功能就是可跨平台性,那大家有没有想过可跨平台性是如何做到的呢? 这就和JVM有关了。
JVM 是一个虚拟的计算机,它在运行时将字节码转换为特定平台的机器码。JVM 的存在使得 Java 程序可以在不同的操作系统和硬件平台上运行,而无需重新编译。
JVM内存结构
运行期数据区域(JDK8之后)
本地方法栈
主要用于执行native方法(java之外的,如C++编写的方法)的,本地方法会创建栈帧(由局部变量表,操作栈帧,动态链接,发方法出口),会出现 StackOverflowError 和 OutOfMemoryError 两种错误。
虚拟方法栈
主要用于执行java方法的,和本地方法栈类似由 Java 虚拟机(JVM)直接执行的方法。它们在 Java 源代码中定义,并在编译后转换为字节码,存储在 .class
文件中。
程序计数器
主要用于存储当前现在线程正在执行的java方法的JVM指令地址,如果是本地方法,则为NULL,这个区域不会出现oom问题。
堆
堆被所有线程共享,主要存储对象实例,在虚拟机启动时候创建,堆分新生代和老年代,新生代里面还有Eden、S0、S1。如果在堆中没有内存完成实例分配,并且堆也无法扩展时会抛出 OutOfMemoryError 异常。
本地内存
本地内存里面主要方法区,在jdk1.8之后,元空间替代了永久代,方法与主要存放类的信息,变量,常量等数据。内存不足时会抛出 OutOfMemoryError 异常。
栈帧里面的局部变量表和方法区(元空间的区别)
栈帧里面的局部变量表存放的方法被调用时的参数,而方法区存放的类的信息。
类加载器
类加载器(ClassLoader)主要的作用是将.Class文件加载的JVM中。
启动类加载器
这是最高级别的类加载器,是由C++实现的,启动类加载器无法被Java程序直接引用。
拓展类加载器
它是Java语言实现的,继承自ClassLoader类,负责加载Java扩展目录(jre/lib/ext或由系统变量Java.ext.dirs指定的目录)下的jar包和类库。扩展类加载器由启动类加载器加载,并且父加载器就是启动类加载器。
系统类加载器
系统类加载器主要是java语言的
-
环境变量
CLASSPATH
指定的路径下的类和资源文件。 -
命令行参数
-classpath
或简写-cp
指定的路径下的类和资源文件。 -
系统属性
java.class.path
指定的路径下的类和资源文件。
自定义类加载器
由开发者自定义的类。
垃圾回收器
垃圾回收(Garbage Collection, GC)是自动管理内存的一种机制,它负责自动释放不再被程序引用的对象所占用的内存,这种机制减少了内存泄漏和内存管理错误的可能性。
执行引擎
负责执行 Java 字节码,管理内存和多线程,以及与垃圾回收器协同工作。
本地方法接口
提供了与本地代码交互的能力,允许 Java 程序访问底层系统资源和遗留系统。
本文很多没有展开详细的说,只是将JVM内存结构阐述一下。本文资源来自于网络,如有侵权联系删除。