HotSpot VM Runtime负责启动和停止hotSpot VM。这篇文章简单介绍了一下一个Web应用的启动和停止。
启动HotSpot VM的组件被称作启动器(launcher)。有许多HotSpot VM启动器,最常用的有Unix/Linux上的java 命令和Windows的java和javaw命令。
启动器执行一系列的操作来启动HotSpot Vm,这些步骤总结如下:
1、解析命令行选项
一些命令行选项被启动器直接使用,比如:-client或者-server,这些命令决定加载JIT complier,其他的命令行被传送到已经启动的HotSpot VM。
2、如果关于堆或者JIT complier的选项没有被命令行明确的置顶,则建立Java堆的大小和JIT complier的类型(client or server)。
这些默认值以来底层系统配置和操作系统而改变。
3、建立环境变量,比如LD_LIBRARY_PATH和CLASSPATH
4、如果命令行里没有指定主入口类(Main -CLASS),那启动器就会从JAR包的清单中得到主入口类的名字。
5、在一个新创建的非原生线程中利用标准的Java本地接口方法JNI_CreateJavaVM建立HotSpot VM。
与一个非原生的线程形成对比,一个源生的线程是当一个新的进程建立的时候被操作系统内核分配的第一个线程。因此,当一个HotSpot VM被创建,源生线程是运行在新建立的HotSpot进程中的第一个被操作系统内核分配的线程。在一个非源生的线程中创建HotSpot VM提供了定制HotSpot VM的功能,例如在Windows上改变栈的大小。
6、一旦HotSpot VM被创建和初始化了,Java的主类(Main-Class)就被加载,启动器就从Main-Class得到了main方法的属性。
7、HotSpot VM利用 Java Native Interface方法 CallStaticVoidMethod调用Java的main方法。同时传入来自命令行的参数序列。
此时,HotSpot VM就在执行由命令行指定的Java程序。
一旦一段Java程序,或者Java main方法执行完成,HotSpot VM必须检查和清理在程序或者方法的执行过程中可能发生的异常。此外,方法的退出状态和程序的退出状态必须被传回他们的调用者。然后Java main方法使用Java Native Interface方法DetachCurrentThread从HotSpot VM中脱离。当HotSpot VM调用了DetachCurrentThread,线程的数量将减少,然后Java Native Interface便知道了什么时候去安全的停止HotSpot Vm并且确保一个线程不再在HotSpot VM中执行并伴随着在栈中没有活跃的帧。
JNI_CreateJavaVM详解
HotSpot Vm的JNI_CreateJavaVM方法的实现在他在HotSpot VM的启动中调用的时候表现在下面的操作。
1、确保在同一时间没有两个线程调用这个方法,并且只有一个HotSpot VM实例在进程中被创建。
因为HotSpot VM创建不能被重新初始化的静态数据结构,在一个进程空间,一个初始化的点到达的时候只能有一个HotSpot VM被创建。对于开发HotSpot VM的工程师来说,启动HotSpot VM的这个阶段是一个类似于只能进不能退的阶段。
2、检查确保支持Java Native Interface的版本。并且为垃圾收集日志初始化好输出流。
3、操作系统模块被初始化,比如随机数生成器,当前进程id,高分辨率计数器、内存页大小和守护页。守护页是非随机存取的内存页,用来限制内存区域的访问。例如:操作系统经常把一个守护页线程栈的栈顶,确保引用不到栈底区域被困住的区域。
4、传递给JNI_CreateJavaVM的命令行参数和属性被解析和存储以备后来使用。
5、标准的系统属性被被初始化,比如:java.version,java.vendor,os.name等等。
6、支持同步、栈、存储器、安全点页的模块被初始化。
7、组件库比如:libzip、libhpi、libjava和libthread被装载。
8、信号处理程序被初始化和设置。
9、线程库被初始化。
10、输出流记录器被初始化。
11、将被用到的代理库(hprof,jdi)完成初始化和启动。
12、持有线程操作需要的特殊数据的线程状态和本地线程存储被初始化。
13、HotSpot VM全局数据的一部分被初始化,比如:事件log,操作系统同步原语,性能统计存储器、内存分配器。
14、这时HotSpot VM就能够创建线程。主线程的Java版本被创建并且隶属于当前的操作系统线程。然而这个线程不被添加到被知道的线程列表中。
15、Java层级的同步被初始化和激活。
16、启动类加载器、代码缓存、解释器、JIT编译器、Java Native Interface、系统字典和整个程序被初始化。
17、现在Java主线程添加到被知道的线程列表中,整个程序即一组需要的全局数据结构将进行完整性检查。
执行所有的HotSpot Vm的重要功能的HotSpot VM 线程被创建,这时,合适的JVMTI(JVM工具接口)将被发布来通知HotSpot VM当前的状态。
18、下列的Java类java.lang.String, java.lang.System, java.lang.Thread, java.lang.ThreadGroup, java.lang.reflect.Method,java.lang.ref.Finalizer, java.lang.Class和剩下的Java类被加载和初始化。这时HotSpot VM就已经被初始化并处于运行状态,但是还没有完全起作用。
19、HotSpot VM信号处理线程开始工作,JIT编译器被初始化,HotSpot的编译代理线程开始工作。其他的HotSpot VM辅助线程比如监控线程、采样线程开始工作。这时HotSpot VM完全起作用了。
20、最后JNIEnv被绑定并返回给调用程序,然后HotSpot VM准备给新的JNI请求服务。
DestroyJavaVM 详解
当HotSpot VM启动的过程中出现错误的时候,DestroyJavaVM方法将被从HotSpot启动器中被调用来关闭HotSpot VM。在HotSpot启动后,当有一个非常严重的错误发生时DestroyJavaVM方法也可以在执行期间被HotSpot VM调用。
HotSpot VM通过DestroyJavaVM方法来关闭需要经历一下一些步骤:
1、等到只有一个普通线程执行的时候。注意:HotSpot VM仍然在起作用。
2、调用Java方法java.lang.Shutdown.shutdown(),该方法调用了Java层级的关闭钩子,如果在退出时终结为true(if finalization-on-exit is true),然后运行Java对象的终结器.
3、通过运行SpotHot层级的关闭钩子(那些通过JVM_OnExit()注册的),停止以下HotSpot线程:分析器、采集器、监控器和垃圾回收线程来为HotSpot VM的退出做准备。发送状态事件给JVMTI,停用JVMTI,然后停止信号线程。
4、调用HotSpot方法JavaThread::exit()释放Java Native Interface句柄块,移除守护页,从被知道的线程列表中当前线程,从这时起,HotSpotVM不能执行任何Java代码。
5、停止HotSpot VM线程。这将引起HotSpot VM将剩下的HotSpot VM线程带到一个安全点然后停止JIT编译器线程。
6、停止追踪Java NativeInterface,HotSpot VM,和JVMTI屏障。
7、将可能运行在本地代码的线程设置为"VM exited"标志。
8、删除当前线程。
9、删除或者移除所有输入/输出流,释放性能统计存储器资源。
10、最后返回调用程序。
相关推荐
Client VM适用于轻量级应用,而Server VM专为高性能的服务器环境设计,提供更优秀的性能。 - **参数调整**:HotSpot VM的性能可以通过设置启动参数来优化,例如使用`-server`选项选择Server VM。内存参数配置也至...
通过这个插件,开发者可以在不离开MyEclipse界面的情况下,进行JVM配置、性能监控、内存分析等一系列操作。这不仅简化了工作流程,也使得问题定位和性能优化变得更加便捷。 1. **配置与启动**:VM插件允许用户...
- **高性能**:即时编译器(JIT)能够动态优化代码执行效率。 #### 四、JVM的核心组件 1. **类加载器**:负责加载类文件到JVM中,处理类之间的依赖关系。 2. **运行时数据区**:包括方法区、堆、栈等,用于存储程序...
4. **类加载过程**:类的生命周期包括加载、验证、准备、解析和初始化。其中,验证确保字节码的安全性,准备阶段分配静态变量的内存并初始化为默认值,解析将符号引用转换为直接引用。 5. **JVM性能调优**:通过...
这样,原生代码可以启动Java程序,控制其生命周期,并在需要时调用Java方法。 4. **设计目标** JNI的主要目标是提供一个不受JVM实现限制的接口,以确保跨平台兼容性。它允许Java开发者充分利用其他语言的能力,...
- 字节码的主要优点包括可移植性、安全性以及高性能。 2. **类加载机制(Class Loading Mechanism)** - 类加载器负责将Java类加载到JVM中。类加载过程包括加载、验证、准备、解析和初始化几个阶段。 - 类加载器...
� Android 更像一款桌面环境为 Java 的 Linux 操作系统。有助于 Google 实现其 " 随时随地为每个人提供信 息 " 的企业战略。 HTC HTC HTC HTC Dream/G1 Dream/G1 Dream/G1 Dream/G1 具体配置 硬件 3.17 英寸 HVGA ...
年轻代负责新创建的对象,而老年代则存储生命周期较长的对象。 - **PermGen**(永久代):特定于Sun HotSpot VM的一种内存区域,用于存储类元数据等信息。需要注意的是,在Java 7及以后版本中,永久代已经被...
Java智能卡开发是一种将Java技术应用于智能卡领域的技术,它使得智能卡具备了更高级别的安全性和可编程性。在本文中,我们将深入探讨Java智能卡开发的关键技术,并结合具体的实例进行讲解。 Java智能卡,通常称为...
Rust是一种系统级编程语言,以其内存安全和高性能而闻名。它的设计目标是实现低级别的控制,同时避免常见的编程错误,如空指针异常和数据竞争。Rust的这些特性使其成为构建高效虚拟机的理想选择,尤其是在实现Just-...
这些知识点是理解和编写高性能Java程序的基础。通过这些知识,我们可以更好地理解Java代码在执行过程中的内存分配和垃圾回收机制,从而编写更加高效的代码。同时,这也是在面试或日常开发工作中,经常会被问到的核心...
理解线程的生命周期、同步机制(如synchronized关键字、wait()、notify()方法)、死锁与活锁的避免,以及线程池的使用(如ExecutorService),是提高程序效率和并发性能的关键。 图形用户界面(GUI)开发在Java中...
总结来说,Android NDK为开发者提供了在Android平台上利用C/C++能力的机会,特别是在需要高性能计算、图形处理或者低级硬件交互时。然而,使用NDK也会带来额外的复杂性,比如内存管理和生命周期管理,因此开发者需要...
书中列举了不同类型的JVM,如经典的HotSpot VM,适用于移动设备的Mobile/Embedded VM,以及针对高性能计算的Azul VM等,展示了Java虚拟机的多样性。 Java虚拟机家族的演变反映了Java技术的发展历程。例如,HotSpot ...
JNI使得开发者可以将C/C++的高性能代码集成到Java应用程序中,或者从C/C++程序中调用Java的类和方法。以下是一个详细的步骤解析: 1. **创建JVM(Java Virtual Machine)**: 创建JVM是调用Java代码的第一步。通过...
从内存分配的角度来看,Java堆可以分为新生代和老年代,以适应不同类型的对象生命周期管理和内存回收策略。 - Java堆还可以划分为多个线程私有的分配缓冲区(Thread Local Allocation Buffer, TLAB),以提高内存...
这些文件名显示了一个关于Java虚拟机(JVM)的深度学习系列,涵盖了从基础到高级的主题,包括字节码、运行时内存、类加载、执行引擎、对象内存布局、垃圾回收以及性能监控和调优。下面是这些知识点的详细解释: 1. ...