浏览 617 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
|
发表时间:2023-11-22
今天给大家讲解一下关于jvm的知识内容,希望对大家在学习jvm的过程中遇到的问题有所帮助,以下是参考资料下载: 资料1:https://pan.baidu.com/s/17hbpzgzhrdecmwgfiishbw 提取码: te99 资料2:https://share.weiyun.com/usocodoc 密码:rdz2uy jvm运行机制概述 类加载机制: 类加载过程由类加载器来完成,即由classloader及其子类实现,有隐式加载和显式加载两种方式。隐式加载是指在使用new等方式创建对象时会隐式调用类加载器把对应的类加载到jvm中;显式加载是指通过直接调用class.forname()把对应的类加载到jvm中。 内存模型(运行时数据区):共享区【方法区、堆】、私有区【虚拟机栈、本地方法栈、程序计数器】、直接内存(不受jvm gc管理)。其中程序计数器是唯一不会出现oom的内存区。 执行引擎:即时编译器、垃圾收集器(按代回收算法:新生代-复制算法(minor gc),老年代-标记整理算法(major gc / full gc)) 类加载机制 类加载过程由类加载器来完成,即由classloader及其子类实现,有隐式加载和显式加载两种方式。隐式加载是指在使用new等方式创建对象时会隐式调用类加载器把对应的类加载到jvm中;显式加载是指通过直接调用class.forname()把对应的类加载到jvm中。 应用类加载器(application classloader):也被称为系统类加载器(system classloader),负责在jvm启动时加载来自java 命令的 -classpath 选项、java.class.path 系统属性,或者 classpath 环境变量所指定的 jar 包和类路径。程序可以通过 classloader 的静态方法 getsystemclassloader() 来获取系统类加载器。如果没有特别指定,则用户自定义的类加载器都以此类加载器作为父类加载器。由java语言实现,父类加载器为extclassloader。 自定义类加载器(user classloader):必须继承 java.lang.classloader。 public class main { public static void main(string[] args) { classloader appclassloader=main.class.getclassloader(); //获取appclassloader system.out.println(appclassloader); classloader extclassloader=appclassloader.getparent(); //获取extclassloader system.out.println(extclassloader); classloader bootclassloader=extclassloader.getparent(); //获取bootclassloader system.out.println(bootclassloader); } } sun.misc.launcher$appclassloader@2a139a55 sun.misc.launcher$extclassloader@7852e922 null 反射机制能够实现在运行时对类进行装载,增加了程序的灵活性。反射机制提供的功能主要有:获取类、获取父类、获取接口、获取成员变量、获取构造器、获取成员方法、运行时创建对象、运行时调用方法。 class demo{ int x; string s; demo(){} demo(int x,string s){ this.x=x; this.s=s; } public void show() { system.out.println(x "," s); } public string show(int x,string s) { system.out.println(x "," s); return "success"; } } java程序内存的分配是在jvm虚拟机内存分配机制下完成。 java内存模型(java memory model ,jmm)就是一种符合内存模型规范的,屏蔽了各种硬件和操作系统的访问差异的,保证了java程序在各种平台下对内存的访问都能保证效果一致的机制及规范。 简要言之,jmm是jvm的一种规范,定义了jvm的内存模型。它屏蔽了各种硬件和操作系统的访问差异,不像c那样直接访问硬件内存,相对安全很多,它的主要目的是解决由于多线程通过共享内存进行通信时,存在的本地内存数据不一致、编译器会对代码指令重排序、处理器会对代码乱序执行等带来的问题。可以保证并发编程场景中的原子性、可见性和有序性。 java栈(虚拟机栈) 同计数器也为线程私有,生命周期与相同,就是我们平时说的栈,栈描述的是java方法执行的内存模型。 每个方法被执行的时候都会创建一个栈帧用于存储局部变量表,操作栈,动态链接,方法出口等信息。每一个方法被调用的过程就对应一个栈帧在虚拟机栈中从入栈到出栈的过程。【栈先进后出,下图栈1先进最后出来】 jvm是可运行 java 代码的假想计算机 ,包括一套字节码指令集、一组寄存器、一个栈、一个垃圾回收,堆 和 一个存储方法域。jvm 是运行在操作系统之上的,它与硬件没有直接的交互。 运行过程: 我们都知道 java 源文件,通过编译器,能够生产相应的.class 文件,也就是字节码文件,而字节码文件又通过 java 虚拟机中的解释器,编译成特定机器上的机器码 。 也就是如下: ① java 源文件—->编译器—->字节码文件 ② 字节码文件—->jvm—->机器码 每一种平台的解释器是不同的,但是实现的虚拟机是相同的,这也就是 java 为什么能够跨平台的原因了 ,当一个程序从开始运行,这时虚拟机就开始实例化了,多个程序启动就会存在多个虚拟机实例。程序退出或者关闭,则虚拟机实例消亡,多个虚拟机实例之间数据不能共享。 这里所说的线程指程序执行过程中的一个线程实体。jvm 允许一个应用并发执行多个线程。 hotspot jvm 中的 java 线程与原生操作系统线程有直接的映射关系。当线程本地存储、缓冲区分配、同步对象、栈、程序计数器等准备好以后,就会创建一个操作系统原生线程。 java 线程结束,原生线程随之被回收。操作系统负责调度所有线程,并把它们分配到任何可用的 cpu 上。当原生线程初始化完毕,就会调用 java 线程的 run() 方法。当线程结束时,会释放原生线程和 java 线程的所有资源。 感谢大家的阅读。 声明:iteye文章欧洲杯足彩官网的版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|