1.什么是JVM?
JVM(Java Virtual Machine)是Java编程语言的关键组成部分之一,它是一个在计算机上运行Java字节码的虚拟机。JVM充当了Java程序和底层操作系统之间的中间层,提供了一种独立于硬件和操作系统的执行环境。
JVM的主要功能是将Java字节码翻译成特定平台的机器码,以便能够在不同的计算机体系结构和操作系统上执行。它还负责内存管理、垃圾回收和安全性等方面的任务。
JVM的体系结构包括以下几个主要组件:
- 类加载器(Class Loader): 负责加载Java字节码文件,并将其转换为JVM内部的数据结构。
- 执行引擎(Execution Engine): 执行字节码指令,将其转换为机器码并执行。
- 内存管理器(Memory Manager): 负责内存的分配和回收,包括堆(Heap)和方法区(Method Area)等内存区域的管理。
- 即时编译器(Just-In-Time Compiler): 将热点代码(被频繁执行的代码)编译成本地机器码,以提高执行效率。
- 垃圾回收器(Garbage Collector): 自动管理内存中不再使用的对象,回收它们的内存空间。
通过JVM,开发人员可以编写一次Java代码,然后将其在不同的操作系统和硬件平台上运行,而无需针对特定平台进行修改。这种平台无关性使得Java成为广泛应用于各种领域的编程语言之一。
2.JVM内存模型
JVM(Java虚拟机)内存模型定义了Java程序在运行时如何使用内存。它将JVM的内存分为不同的区域,每个区域有特定的功能和用途。以下是JVM内存模型中最常见的区域:
- 程序计数器(Program Counter): 程序计数器是一块较小的内存区域,它记录当前线程执行的字节码指令的地址。当线程执行Java方法时,程序计数器会记录当前执行的指令的位置,用于线程切换和指令的恢复。
- Java堆(Java Heap): Java堆是JVM中最大的一块内存区域。它是被所有线程共享的内存区域,用于存储Java对象实例。堆被划分为新生代和老年代两部分。新创建的对象首先被分配在新生代的Eden区域,经过一定的条件后会被移到存活区域,最终可能被移到老年代。
- 方法区(Method Area): 方法区是被所有线程共享的内存区域,用于存储类信息、常量、静态变量、即时编译器编译后的代码等数据。在Java 8及之前的版本,方法区被实现为永久代(Permanent Generation),而在Java 8之后,永久代被元数据区(Metaspace)所取代。
- 运行时常量池(Runtime Constant Pool): 运行时常量池是方法区的一部分,用于存储编译时生成的各种字面量和符号引用。它包括类和接口的全限定名、字段和方法的名称和描述符、常量值等。
- 虚拟机栈(VM Stack): 虚拟机栈是每个线程独享的内存区域,用于存储方法调用的栈帧。每个方法在执行时都会创建一个栈帧,栈帧包含了方法的局部变量、操作数栈、方法返回地址等信息。
- 本地方法栈(Native Method Stack): 本地方法栈类似于虚拟机栈,但用于执行本地(Native)方法。本地方法栈也是每个线程独享的,用于支持本地方法的执行。
- 程序内存(Direct Memory): 程序内存并不是JVM运行时数据区的一部分,但也被频繁使用。它是使用NIO(New I/O)库进行直接内存操作的一种方式,通过使用Native函数库直接分配堆外内存。
3.main函数
// 基础
public class HelloWorld{
public static void main(String args[]){
System.out.println("Hello World!");
}
}
//cmd编译运行
/*
javac HelloWorld.java
java HelloWorld
*/
// 1. javac+空格+文件名.java”指令编译源文件
// 2. java+空格+文件名”指令运行源代码
解析Java Main函数
public 公有属性 ,它可以在同一个包内访问,也可以在不同包内访问
class 代表一个类
HelloWorld l类名
static 表示“全局”或者“静态”的意思,用来修饰成员变量和成员方法,也可以形成静态static代码块,但是Java语言中没有全局变量的概念。 被static修饰的成员变量和成员方法独立于该类的任何对象。 也就是说,它不依赖类特定的实例,被类的所有实例共享。
void 不是函数,是方法的修饰符,void的意思是该方法没有返回值,意思就是方法只会运行方法中的语句,但是不返回任何东西
main 主方法是类的入口点,它定义了程序从何开始;主方法提供对程序流向的控制,Java编译器通过主方法来执行程序。启动了几个main函数就启动了几个java应用,同时也启动了几个java的虚拟机。
String args[] String args[ ]或者String[ ] args表示给主方法传一个字符串数组. 而args是一个字符串数组的变量名,不是关键字,是arguments的缩写,只是一个默认名,一般都习惯性照写
一、为什么 main 方法是静态的(static)?
1.正因为 main 方法是静态的,JVM 调用这个方法就不需要创建任何包含这个 main 方法的实例。
2.因为 C 和 C++ 同样有类似的 main 方法作为程序执行的入口。
3.如果 main 方法不声明为静态的,JVM 就必须创建 main 类的实例,因为构造器可以被重载,JVM 就没法确定调用哪个 main 方法。
4.静态方法和静态数据加载到内存就可以直接调用而不需要像实例方法一样创建实例后才能调用,如果 main 方法是静态的,那么它就会被加载到 JVM 上下文中成为可执行的方法。
二、为什么main方法是公有的(public) ?
Java 指定了一些可访问的修饰符如:private、protected、public,任何方法或变量都可以声明为 public,Java 可以从该类之外的地方访问。因为 main 方法是公共的,JVM 就可以轻松的访问执行它。
三、为什么 main 方法没有返回值(Void)?
因为 main 返回任何值对程序都没任何意义,所以设计成 void,意味着 main 不会有任何值返回。