【JVM】体系结构及其细节
JVM
JVM运行在操作系统之上,与硬件没有直接的交互。引入Java语言虚拟机后,Java语言在不同平台上运行时不需要重新编译。Java语言使用Java虚拟机屏蔽了与具体平台相关的信息,使得Java语言编译程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。
JVM的体系结构
Java栈、本地方法栈和程序计数器是线程私有的,内存占用少,几乎不存在垃圾回收。
方法区和堆所有线程共享,存在大量垃圾回收。
类装载器
负责加载class文件,class文件在文件开头有特定的文件标识(cafe babe),将class文件加载到内存中,并将这些内容转换成方法区中运行时数据机构,并且ClassLoader只负责class文件的加载,运行由执行引擎负责。
虚拟机自带的加载器:
- 启动类加载器BootStrap【C++】
- 扩展类加载器Extension【Java】
- 应用程序类加载器AppClassLoader(系统类加载器):加载当前应用的classpath的所有类
用户自定义的加载器:java.lang.ClassLoader的子类
public static void main(String[] args) {
Object object = new Object();
//打印null
System.out.println(object.getClass().getClassLoader());//jdk自带的类--BootStrap MyObject myObject = new MyObject();
//sun.misc.Launcher$AppClassLoader@18b4aac2
System.out.println(myObject.getClass().getClassLoader());//自定义的类--AppClassLoader
//sun.misc.Launcher$ExtClassLoader@4554617c
System.out.println(myObject.getClass().getClassLoader().getParent());
//null
System.out.println(myObject.getClass().getClassLoader().getParent().getParent());
}
sun.misc.Launcher:JVM相关调用的入口程序
双亲委派机制
当一个类受到类加载请求,不会自己去加载,而是委派给父类完成,所有的加载请求都应该传送到启动类加载器中,只有当父类加载器反馈自己无法完成请求的时候(加载路径下没有需要加载的Class),子类加载器才会尝试自己去加载。
双亲委派机制的好处:
- 防止重复加载同一个
.class,
通过委派给父类加载器,加载过了,就不用再加载一遍。保证数据安全。 - 保证核心
.class
不能被篡改。通过委派,不会去篡改核心.clas
,即使篡改也不会去加载,即使加载也不会是同一个.class
对象了。不同的加载器加载同一个.class
也不是同一个Class
对象。这样保证了Class
执行安全。【防止污染jdk源码】
沙箱安全机制
Java安全模型的核心就是Java沙箱,沙箱是一个限制程序运行的环境。沙箱机制就是将 Java 代码限定在虚拟机(JVM)特定的运行范围中,并且严格限制代码对本地系统资源访问,通过这样的措施来保证对代码的有效隔离,防止对本地系统造成破坏。沙箱主要限制系统资源访问,系统资源包括CPU、内存、文件系统、网络
。不同级别的沙箱对这些资源访问的限制也可以不一样。所有的Java程序运行都可以指定沙箱,可以定制安全策略。
native接口和方法
普通方法放在Java栈中,native方法放在本地方法栈中。native是一个关键字,native方法在源码中只有声明,没有实现。
本地接口:为了融合其他编程语言,需要调用c/c++程序的时候,在内存中开辟一块区域处理native代码,在执行引擎执行的时候加载本地库。【目前使用越来越少,一般与硬件相关的应用会使用】
本地方法栈:在栈中登记native方法,在执行引擎执行的啥时候加载本地方法库。
程序计数器(PC寄存器)
用于记录方法之间的调用和执行情况。每个线程都有一个程序计数器,线程私有,就是一个指向方法区中的方法字节码的指针,用来存储指向下一条指令的地址),也即将要指向的指令代码,由执行引擎来读取下一条指令,是一个非常小的内存空间,几乎可以忽略不计。
实际上就是当前线程所指向的字节码的行号指示器,字节码解释器通过改变计数器的值来选取下一条需要执行的字节码指令,如果执行的是native方法,则计数器是空的。用来完成分支、循环、跳转、异常处理、线程恢复等基础功能,不会发生内存溢出(OOM)错误。
方法区
方法区是线程共享的运行时内存区域,它存储每个类的结构信息。例如:常量池、字段、方法数据、构造函数、普通方法的字节码内容。【方法区是一个规范,不同的虚拟机中有着不一样的实现,例如永久代和元空间】
实例变量存在堆内存中,和方法区无关
Java栈
栈负责运行,堆负责存储。
Java栈负责程序的运行,在线程创建的时候创建,生命周期跟随线程的生命周期,是线程私有的,线程结束,内存释放。Java栈不存在垃圾回收的问题,线程一结束,栈内存就释放了。
Java的8种基本类型,对象的引用变量和实例方法都是在函数的栈内存种分类。
栈内存储的数据:
- 本地变量:输入、输出参数及方法内的变量(局部变量)
- 栈操作:出栈、入栈的操作
- 栈帧数据:类文件、方法等
什么是栈帧?参考 ☞ https://www.jianshu.com/p/b666213cdd8a
Person p = new Person()
引用变量p存在栈内存中 实例变量new Person()存在堆内存中
栈的运行原理:栈中的数据已栈帧的格式存在,栈帧是一个内存区块,是一个关于方法和运行期数据的数据集。其大小和JVM的实现有关,通常在256K~756K之间,1Mb左右
当方法A被调用是产生一个栈帧F1被压入栈中,A调用了B,B的栈帧F2被压入栈,B调用C,C的栈帧F3被压入栈帧。执行完毕后,F3、F2和F1一次弹出。
栈异常:java.lang.StackOverflowError (SOF)属于错误
堆、栈和方法区之间的关系
HotSpot是使用指针的方式来访问对象【Java HotSpot补充:https://www.jianshu.com/p/714eb5adadb9】
Java堆会存放访问类元数据(类的结构信息)的地址
reference存储是对象的地址
Java堆中可以存在多个Person实例:p1、p2、p3。而p1,p2,p3都指向方法区中同一个对象类型数据(Person Class),即类的结构信息。
【JVM】体系结构及其细节的更多相关文章
- 46张PPT讲述JVM体系结构、GC算法和调优
本PPT从JVM体系结构概述.GC算法.Hotspot内存管理.Hotspot垃圾回收器.调优和监控工具六大方面进行讲述.(内嵌iframe,建议使用电脑浏览) 好东西当然要分享,PPT已上传可供下载 ...
- JVM 体系结构概述 (一)
一.jvm运行在操作系统之上的,它与硬件没有直接交互: 二.JVM体系结构概览 JVM的基本结构:类加载器.执行引擎.运行时数据区.本地方法接口: 过程:class文件 ----> 类加载器 - ...
- JVM体系结构之三:方法区之2(jdk1.6,jdk1.7,jdk1.8下的方法区变迁)
方法区 方法区存储虚拟机加载的类信息,常量,静态变量,即时编译器编译后的代码等数据.HotSpot中也称为永久代(Permanent Generation),(存储的是除了Java应用程序创建的对象之 ...
- 第七章 JVM体系结构与工作方式
JVM能跨计算机体系结构来执行Java字节码,主要是由于JVM屏蔽了与各个计算机平台的软件和硬件之间的差异. 7.1 JVM体系结构 7.1.1 何谓JVM 模拟一个计算机来达到一个计算机所具有的计算 ...
- JVM体系结构之一:总体介绍
一.Java的内存区域划分 Java 虚拟机在执行Java程序的时候会把它管理的内存区域划为几部分,这一节我们就来解析一下Java的内存区域. Java的内存区域主要分为五部分: 程序计数器(PC) ...
- JVM体系结构之三:方法区之1
一.简介 方法区在JVM中也是一个非常重要的区域,它与堆一样,是被线程共享的区域.在方法区中,存储了每个类的信息(包括类的名称.方法信息.字段信息).静态变量.常量以及编译器编译后的代码等. 方法区( ...
- JVM体系结构详解
每个Java开发人员都知道字节码将由JRE (Java运行时环境)执行.但是很多人不知道JRE是Java Virtual Machine(JVM)的实现,它分析字节码.解释代码并执行代码.作为开发者, ...
- [转帖]JVM总结--JVM体系结构
JVM总结--JVM体系结构 https://blog.csdn.net/samjustin1/article/details/52215274 需要不断的学习才可以. 2016年08月15日 22: ...
- JVM体系结构及优化
源文档:https://docs.oracle.com/javase/8/docs/technotes/guides/vm/index.html JVM体系结构 方法区,类加载器,堆,Java ...
- JVM 体系结构与工作方式
.katex { display: block; text-align: center; white-space: nowrap; } .katex-display > .katex > ...
随机推荐
- 2019 ICPC 南京网络赛 H-Holy Grail
As the current heir of a wizarding family with a long history,unfortunately, you find yourself force ...
- Android JetPack组件-CameraX初探
CameraX 又是一个 Google 推出的 JetPack 组件 ,是一个新鲜玩意儿,故给大家分享下我在项目中的使用过程心得.. CameraX 是什么? Google 开发者文档 对 Camer ...
- 解决虚拟机中linux系统无法使用本机无线wifi联网的问题
VMware Workstation 在嵌入式开发中经常会遇到,但是显示大多数人使用开发环境是Win10 + 无线网卡,针对这种情况,需要配置虚拟机的上网环境使用的是NAT模式,将配置过程进行描述: ...
- xenomai内核解析之嵌入式实时linux概述
Linux系统作为一个GPOS(通用操作系统)发展至今已经非常成熟可靠了,并且由于遵循GPL协议,开放所有系统源代码,非常易于裁剪.更重要的是,与其他开源的GPOS或RTOS相比,Linux系统支持多 ...
- Codeforces 1332 D. Walk on Matrix(构造矩阵)
怎么构造呢? \(首先我们不可能去构造一个2000*2000的矩阵,那太复杂了\) \(也许我们可以看看2*2的矩阵??\) \[\left[ \begin{matrix} x&y\\ z&a ...
- 使用 Minikube 安装 Kubernetes
概述: 单机低配置主机也可以玩转kubernetes集群.该文章是将介绍使用Minikube安装Kubernetes集群(一般用于本地/开发环境). 配置环境: 硬件:CPU 至少2个核心,至少2.5 ...
- Spring Boot学习 之 Spring Boot Actuator(一)
Spring Boot版本:2.1.4.RELEASE 启用: spring-boot-actuator模块提供了一系列的用于监控的端点.最简单的开启这个功能的方法就是,在pom文件中添加如下的依赖. ...
- Spring Batch 读 10 万条记录,写到 MongoDB
实践内容 从 MariaDB 一张表内读 10 万条记录,经处理后写到 MongoDB . 具体实现 1.新建 Spring Boot 应用,依赖如下: <!-- Web 应用 --> & ...
- FOC 电流采样方案对比(单电阻/双电阻/三电阻)
如果本文帮到了你,帮忙点个赞: 如果本文帮到了你,帮忙点个赞: 如果本文帮到了你,帮忙点个赞: 创作不易 谢谢支持 文章目录 1 电流采样的作用 2 硬件架构 3 采样关键 4 采样方案 5 三电阻采 ...
- printf小结
下午健身前和lxt兄弟讨论了一个关于 printf 输出的问题,恰巧以前见过类似的,回来写一个收获总结. 首先看一个这样一个例子 #include<cstdio> int i; int m ...