一.Java文件编译的过程
- 编写.java文件
- 由javac将.java文件编译成字节码.class文件
- JVM将.class文件编译成二进制代码文件
二.Java跨语言平台
因为jvm可以根据不同的操作系统编写不同的机器码
三.Jdk、Jre、JVM的区别
JVM:将.class字节码编译为适应当前操作系统的机器码
JRE:java核心类库+Jvm,java运行的最小环境
JDK:jre+开发工具(如javac编译器、jar打包工具)
四.JVM内存管理
内存管理是指JVM对运行时内存的分配、使用和回收机制,核心目标是自动管理内存,减少开发者手动操作,避免内存泄漏和溢出。其内存结构主要分为线程共享区和线程私有区,配合垃圾回收(GC)机制实现内存高效利用。
1.JVM内存区域划分
线程共享区:堆和方法区
堆:
java虚拟机所管理的内存中最大的一块,存放了所有对象实例和数组(new出来的对象),jvm中内存最大的一块,是垃圾回收得主要区域。根据Java虚拟机规范的规定,java堆可以处于物理上不连续的内存空间中。如果堆中没有内存可以完成实例分配,并且堆也无法再扩展时,将会抛出OutOfMemoryError异常。
分为:年轻代和老年代
年轻代:新创建的对象会分配在这里,采用复制算法回收(存活对象复制到另一个区域,清空原有区域)
老年代:长期存活对象存放点,使用标记-清除或者标记-整理的办法回收
方法区(JDK8后称为元空间):
方法区是所有线程共享的内存区域,存放类元数据、静态变量、常量池,使用本地内存,默认无上限,可通过-XX:MaxMetaspaceSize限制,避免永久代内存溢出。当方法区无法满足内存分配需求时,抛出OutOfMemoryError异常。
线程私有区:虚拟机栈、本地方法栈、程序计数器
虚拟机栈:
每个方法执行时创建一个栈帧,存储局部变量表、操作数栈、动态链接、方法出口等。栈深度过大会导致StackOverflowError(如递归无终止);内存不足时可能OOM(极少发生)。
本地方法栈:
为JVM调用Native方法(如C/C++库)服务,逻辑与虚拟机栈类似,是虚拟机栈为虚拟机执行Java方法(也就是字节码)的服务native关键字的方法是看不到的,必须要去oracle官网去下载才可以看的到,而且native关键字修饰的大部分源码都是C和C++的代码,所以本地方法栈中就是C和C++的代码。
程序计数器:
是一块较小的内存空间。记录当前线程执行的字节码行号(如正在执行哪条指令),是JVM中唯一不会OOM的区域。由于Java虚拟机的多线程是通过线程轮流切换并分配处理器执行时间的方式来实现的,一个处理器都只会执行一条线程中的指令。因此,为了线程切换后能恢复到正确的执行位置,每条线程都有一个独立的程序计数器,各个线程之间计数器互不影响,独立存储。
2.垃圾回收(GC)
回收不再被引用的对象占用的内存,避免内存泄漏。主要回收堆内存和元空间。
判断对象是否可回收:
引用计数法:有循环引用的问题
可达性分析法:从“GC Roots”(如栈中引用、静态变量等)出发,不可达的对象标记为可回收。
3.内存溢出(OOM)和内存泄漏
内存溢出:
堆溢出:对象太多且无法回收
元空间溢出:加载太多类
栈溢出:方法递归深度过大
内存泄漏:
对象已无用但仍被引用(如静态集合缓存未清理),导致GC无法回收,最终OOM。
五. JVM运行时数据区
包括方法区、堆、程序计数器、本地方法栈、虚拟机栈
六. Java内存结构
1.直接内存
Java中的直接内存(Direct Memory)是一种堆外内存(不在JVM堆内分配),直接由操作系统管理,可通过Java NIO(New IO)库访问,主要用于提升IO操作性能。但是还是会受到本机总内存大小限制
直接内存与堆内存的区别:
直接内存申请空间耗费很高的性能,堆内存申请空间耗费比较低
直接内存的IO读写的性能要优于堆内存,在多次读写操作的情况相差非常明显
核心特点:
(1)非堆内存:不属于JVM运行时数据区(堆、栈、方法区等),而是直接从操作系统申请的内存,大小受本机总内存限制(而非JVM堆大小)。
(2)高效IO:避免了Java堆内存与Native内存(操作系统内存)之间的数据拷贝。例如,文件/网络数据可直接在直接内存与IO设备间传输,无需经过JVM堆中转,大幅提升读写效率。
(3)手动/自动回收
分配:通过 ByteBuffer.allocateDirect(capacity)或 Unsafe.allocateMemory()手动申请。
回收:不受JVM GC直接管理,需通过Cleaner机制或显式调用 System.runFinalization()触发释放;当关联的DirectByteBuffer对象被GC回收时,直接内存会自动释放(通过虚引用跟踪)。
2. JVM的字节码执行引擎
负责将字节码文件(.class)翻译成机器码并执行,是实现“一次编译、到处运行”的关键。它通过解释执行或编译执行的方式处理字节码,同时管理运行时方法的调用与数据流转。
3. 垃圾收集系统
是自动内存管理的核心,负责识别并回收堆内存中不再被引用的对象,释放内存资源,避免内存泄漏和溢出。它通过“自动回收”替代手动内存管理,是Java“一次编写、到处运行”的重要保障。
回收区域:
堆内存(主要目标):年轻代(Eden、Survivor区)和老年代。
方法区(元空间):回收废弃的类元数据、常量池(JDK8后元空间用本地内存,GC频率较低)。
本文参考博客:https://blog.csdn.net/weixin_43122090/article/details/105093777
4688

被折叠的 条评论
为什么被折叠?



