JVM基础

JRE:运行java字节码的环境。它是运行已编译java程序所需要的所有内容的集合,主要包括java虚拟机JVM和java基础类库(class library)

JVM是Java Virtual Machine的缩写,即Java虚拟机。‌它是一个虚构的计算机,通过在实际的计算机上仿真模拟各种计算机功能来实现。JVM的作用是在不同的平台上提供一个统一的运行环境,使得Java程序能够在任何安装了JVM的设备上运行,而不需要针对每个平台进行修改

JDK:提供给开发者使用的工具,它包含了JRE,同时还包含了编译java、源码的编译器javac以及一些其它工具,如javadoc(文档注释工具)、jdb(调试器)、jconsole(基本JMX的可视化监控工具)、javap(反编译工具)等等。

JMM:java内存模型

        JMM就是java内存模型,因为在不同的CPU厂商下,CPU的实现机制都有一些不同,在内存和一些指令上都会存在一些差异。所以JMM就是为了屏蔽掉硬件和操作系统带来的差异,放Java程序可以在不同硬件和操作系统下,实现并发编程的原子性、可见性、禁止指令重排。简单地说,就是CPU内存和JVM内存之间的一个规则,这个规范可以将JVM的字节码指令CPU能够为CPU能够识别的指令。

 Doug Lea工作站对内存模型的描述中可以看到JMM帮我们做了哪些事情,其中重要的是基于三大特性(原子性、可见性、禁止指令重排),对应不同的CPU做不同的实现。

https://gee.cs.oswego.edu/dl/jmm/cookbook.html  

面向对象

        对象的加载过程:

        1、检查加载:首先检查这个指令的参数是否能在常量池中定位到一个类的符号引用(符号引用:符号引用以一组符号来描述所引用的目标),并且检查类是否已经被加载、解析和初始化过。

        2、分配内存

        接下来虚拟机将为新生对象分配内存。为对象分配空间的任务等同于把一块确定大小的内存从java堆中划分出来。

        分配方式:指针碰撞,空闲列表。解决并发安全问题:CAS失败重试机制,本地线程分配 缓冲(ThreadLocal Allocation Buffer,TLAB)。指针碰撞:如果Java堆中内存是绝对规整的,所有用过的内存都放在一边,空闲的内存存放在另一边,中间放一个指针作为分界点的指示器,那所分配内存就仅仅是把那个指针向空闲空间那边挪动一段与对象大小相等的距离,这就是指针碰撞。空闲列表:如果Java堆中的内存并不是规整的,已使用的内存和空闲的内存相互交错,那就没有办法简单地指针碰撞了,虚拟机就必须维护一个列表,记录上哪些内存可用的,在分配的时候从列表中找到一块足够大的空间划分给对象实例,并更新列表上的记录,这种分配方式称为“空闲列表”。选择哪种分配方式由Java堆是否规则决定,而Java堆是否规整又由采用的垃圾收集器是否带有压缩整理功能决定。如果是Serial、ParNew等带有压缩的整理的垃圾回收器的话,系统采用的是指针碰撞,既简单又高效。如果是使用CMS这种不带压缩(整理)的垃圾回收器的话,理论上只能采用较复杂的空闲列表。

        3、内存空间初始化

                不是构造方法,内存分配完成后,虚拟机需要将分配到的内存空间都初始化为零值。这一步操作保证了对象的实例字段在java代码中可以不赋初始值就直接使用,程序能访问到这些字段的数据类型所对应的零值。

        4、设置,接下来虚拟机要对对象进行必要的设置,例如这个对象是哪个类的实例、如何才能找到类的元数据信息(Java classes在Java hotspot VM内部表示为类元数据)、对象的哈希码、对象的GC分代年龄等信息。这些信息存放在对象的对象头中。

        5、对象初始化。在上面工作都完成之后,从虚拟机的视角来看,一个新的对象已经产生了,但从java程序的视角来看,对象创建才刚刚开始,所有的字段都还为零值。所以,一般来说,执行new指令之后会接着把对象按照程序员的意愿进行初始化(构造方法),这样一个真正可用的对象才算真正产生出来。

异常

        java的异常处理会影响我们程序的性能,创建一个异常非常慢,抛出一个异常又得消耗1-5ms

的时间,当一个异常在应用程序的多个层级之间进行传递时,会拖垮我们整个应用程序。

        仅在异常情况下使用异常,在可恢复的异常情况下使用异常,心得使用异常有利于java开发,但是在应用中最好不要捕获太多的调用栈,因为在很多情况下都不需要打印调用栈知道哪里出错了。

        使用try-with-resources是JDK1.7中提供的一个异常处理机制,它能够很容易地关闭try-catch语句中的资源。所谓的资源是指在程序结束后,必须关闭的对象。try-with-resources语句确保了每个资源在语句结束时关闭。所有实现了java.lang.AutoCloseable接口(也包括实现了java.io.Closeable的所有对象)的对象可以作为资源。
        

    public static void main(String[]args]{        try(Resource res = new Resource()){//TODO 业务逻辑处理}catch(Exception e){System.out.print(e.printStackTrace());}}class Resource implements AutoCloseable{void doSome(){System.out.print("do something");}@Overridepublic void close() throw Exception{System.out.print("resource is closed");}}

以上代码编译后为自动生成finally代码块,里面会对try里面的Resource资源进行判空,如果非空就对其进行关闭。

        在JDK9里面可以直接在try前面声明final类型的Resource,然后try-with-sources里面写上变量名即可。

集合

线程

IO

网络通信

        java中的锁可分为乐观锁和悲观锁,乐观锁和悲观锁是两个概念,而不是特指的两种锁。java中针对这两个概念作了落地。乐观锁认为操作的时候没有线程与我并发,正常地去写,但是如果有并发可能会失败,返回false,成功返回true,不会阻塞和等待,失败了就再试一次,直到成功为止。悲观锁则认为在操作的时候有线程与我并发,所以在操作之前就一定得先去竞争锁资源,如果拿不到这个资源,线程就挂起、阻塞等待。乐观锁使用CAS实现,在java中使用UnSafe类中的native方法形式存在的,到了底层,就是CPU支持的原子指令,比如x86下的cmpxchg操作指令。悲观锁使用synchronizedLock锁实现。它们的核心区别就是是否会挂起你的线程,线程在用户态时不能这么做,需要用户态转换到内核态,让OS操作系统去唤醒挂起的线程,这个用户态和内核态的切换就比较耗时。

虽然乐观锁有一定的优势,但也不是所有场景都适合。如果竞争特别激烈,导致乐观锁有一直失败,那CPU就需要一直去调度它,但是又一直失败,就会很浪费CPU资源,从而导致CPU占用率飙高。在操作系统下,线程就只有一个阻塞状态BLOCKED,java中为了更好地排查问题,给线程提供了三种阻塞的状态,BLOCKED、WAITING、TIMED_WAITING.

CAS在java层面上来说CAS是不涉及到锁的情况,因为它不涉及线程的挂起和唤醒操作。可以为是无锁操作。但CAS在CPU内部是基于cmpxchg指令去做的。而且CPU也是多核的。那么在多个核心都去对一个变量进行CAS操作时,x86的CPU中,会添加lock前缀指令,可能会基于缓存行锁,或者是基于总线锁,只让一个CPU内核执行这个CPU操作。一般在平时的开发中,99%的场景下都涉及不到,除非开发一些中间件、框架之类时,可能会涉及到,一般看到的都是在JUC包下的并发工具里涉及到。比如ReentrantLock、synchronized、ThreadPoolExecutor,CountdownLatch等。

        java中锁的底层实现CAS,主要就是cmpxchg指令;synchronized:主要是对象头里面的MarkWord中的锁升级机制,无锁、偏向锁、轻量级锁、重量锁;Lock锁中的AQS

反射

java反射是java的一个特性,它允许程序在运行时对自身进行检查,并且能够操作类、接口、字段 、方法等。反射提供强大的功能,但也带来一些技术难点。

基本原理

1、类的加载:java反射始于类的加载。当使用Class.forName()或其它类加载器加载类时,JVM会读取类的字节码文件,并将其转化为Class对象,这个对象包含了元数据信息,如类名、包名、父类、实现的接口、字段、方法等。

2、:获取类的信息:通过Class对象,我们可以获取类的各种信息,例如,使用getMethod()方法猎取类的所有公共方法,使用getDeclaredFields()方法猎取类的所有字段(包括私有字段)。

3、动态调用:反射不仅能允许我们获取类的信息,还允许我们动态地创建对象、调用方法、修改字段值等。通过newInstance()方法可能创建类的实例,通过getMethod()猎取方法并使用invoke()方法调用它。

技术难点:

1、性能:比直接操作代码更慢,因为反射涉及到动态解析和类型检查等。

2、安全性:反射允许访问类的私有成员,这可能导致安全漏洞。如果反射被恶意代码使用,可能会破坏系统的安全性。

3、复杂性:反射的操作相对比较复杂,需要深入理解java的类型系统和类加载机制。另外反射可能会带来一些安全性的问题。可以通过以下措施来尽量减少安全问题:

1、访问控制:java提供了访问控制修饰符来控制对类的成员的访问。虽然反射可以安全码这些限制,但我们应该避免在不需要时这样做。在设计API时, 应该只暴露必要的公共接口,并隐藏敏感的内部实现。

2、代码签名和验证:JVM在加载类时会对类的字节码进行验证,以确保符合java语言的规范。此外,还可以使用代码签名来验证类的来源是否可信,这可防止恶意代码被加载到JVM中。

3、最小权限原则:在编写使用反射的代码时,应遵循最小权限原则,则只请求执行所需任务所需的最小权限,例如,如果只需要可以读取某个字段的值,就不要请求修改该字段的权限。

4、安全管理器:java提供了一个安全管理器(SecurityManager)类,它允许应用程序定义自己的安全策略。通过实现自定义的安全管理器,可以限制反射的使用,例如禁止加载来自不受信息的源的类。

5、代码审计和测试:对使用反射的代码进行严格的审计和测试是确保安全性的重要步骤。这包括检查是否有不安全的反射使用,验证输入数据的有效性以及确保代码符合安全最佳实践等。

泛型

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/6203.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

vm虚拟机中添加网卡却在network-scripts文件找不到,解决方法

前言 进入network-scripts文件发现只有eth0网卡 ifconfig发现添加进去了 解决方法 nmcli d s #查看目前服务器中所有网卡 手动启用该接口 nmcli d connect eth1 重启网卡 systemctl restart network 解决问题

keepalive+mysql8双主

1.概述 利用keepalived实现Mysql数据库的高可用,KeepalivedMysql双主来实现MYSQL-HA,我们必须保证两台Mysql数据库的数据完全一致,实现方法是两台Mysql互为主从关系,通过keepalived配置VIP,实现当其中的一台Mysql数据库…

论文阅读(一种基于球面投影和特征提取的岩石点云快速配准算法)

目前存在的问题: 在图像配准研究方面比点云配准更早、更有发展。相对之下,点云配准方法不成熟,将图像配准的思想与ICP相结合。 文章主要研究内容: 单站扫描仪的点云数据通过球极坐标转换为数字图像提取图像特征并去除边缘点&#…

人脸检测之MTCNN算法网络结构

MTCNN(Multi-task Cascaded Convolutional Networks)是一种用于人脸检测和关键点检测的深度学习模型,特别适合在复杂背景下识别出多尺度的人脸。它通过多任务学习来实现人脸检测和人脸关键点定位(如眼睛、鼻子、嘴巴的位置&#x…

CocosCreator 构建透明背景应用(最新版!!!)

文章目录 透明原理补充设置截图以及代码step1: electron-js mian.jsstep2:ENABLE_TRANSPARENT_CANVASstep3:SOLID_COLOR Transparentstep:4 Build Web phonestep5:package electron-js & change body background-color 效果图补充 透明原理 使用Cocos creator 做桌面应用开…

【设计模式】结构型模式(三):桥接模式、外观模式

结构型模式(三):桥接模式 4.桥接模式(Bridge)4.1 结构4.2 示例4.2.1 抽象类4.2.2 细化抽象类4.2.3 实现类接口4.2.4 具体实现类4.2.5 客户端 5.外观模式(Facade) 4.桥接模式(Bridge&…

初识Linux

Linux指令 输入指令,实际上是在Linux环境下,做Windows的操作。 ls指令 语法: ls [选项][目录或文件] 功能: 对于目录,该命令列出该目录下的所有子目录与文件。 对于文件,将列出文件名以及其他信息。 常…

【Uniapp】Uniapp Android原生插件开发指北

前言 在uniapp开发中当HBuilderX中提供的能力无法满足App功能需求,需要通过使用Andorid/iOS原生开发实现时,或者是第三方公司提供的是Android的库,这时候可使用App离线SDK开发原生插件来扩展原生能力。 插件类型有两种,Module模…

软考教材重点内容 信息安全工程师 第1章 网络信息安全概述

第 1 章 网络信息安全概述 1.1.1 网络信息安全相关概念 狭义上的网络信息安全特指网络信息系统的各组成要素符合安全属性的要求,即机密性、完整性、可用性、抗抵赖性、可控性。 广义上的网络信息安全是涉及国家安全、城市安全、经济安全、社会安全、生产安全、人身安…

Redis ——发布订阅

问题引入: 服务器A、B、C、D,客户端:C1,C2,C3,C4; 客户端基于集群聊天服务器的负载均衡分配; C1 被分配到A,C2 被分配到B,C3 被分配到C,C4 被分…

【网络】传输层协议TCP(下)

目录 四次挥手状态变化 流量控制 PSH标记位 URG标记位 滑动窗口 快重传 拥塞控制 延迟应答 mtu TCP异常情况 四次挥手状态变化 之前我们讲了四次挥手的具体过程以及为什么要进行四次挥手,下面是四次挥手的状态变化 那么我们下面可以来验证一下CLOSE_WAIT这…

单链表专题

单链表 1. 链表的概念2. 链表的分类3. 实现无头单向非循环链表(单链表)3.1 单链表的声明3.2 单链表的打印3.3 尾插3.4 头插3.5 尾删3.6 头删3.7 查找3.8 在指定位置之前插入数据3.9 在指定位置之后插入数据3.10 删除指定节点3.11 销毁链表 4. 一些细节4.…

K8S篇(基本介绍)

目录 一、什么是Kubernetes? 二、Kubernetes管理员认证(CKA) 1. 简介 2. 考试难易程度 3. 考试时长 4. 多少分及格 5. 考试费用 三、Kubernetes整体架构 Master Nodes 四、Kubernetes架构及和核心组件 五、Kubernetes各个组件及功…

中国500米分辨率逐月平均EVI数据集(2000-2022)

EVI是在归一化植被指数(NDVI)的基础上进行改进的,通过卫星不同波段探测数据组合而成。EVI考虑了大气校正,包括大气分子、气溶胶、水汽和臭氧等因素,以解决NDVI容易饱和的问题。EVI的计算公式考虑了蓝光和红光波段&…

二级列表联动

介绍 本示例主要介绍了List组件实现二级联动(Cascading List)的场景。 该场景多用于商品种类的选择、照片不同类型选择等场景。 效果图 使用说明: 滑动二级列表侧控件(点击没用),一级列表随之滚动。&…

基于matlab的人民币面额识别

本文通过分析第五版人民币的特征,利用纸币中央数字的特征提取和识别的方法,通过matlab软件实现对第五版人民币的100元、50元和20元的识别。 Matlab函数介绍 Imread 函数imread用于读取图片文件中的数据。 调用格式: A imread(filename,…

Docker篇(实际应用)

目录 一、MySQL 部署 1. 拉取 MySQL 镜像 2. 查看镜像 3. 创建 MySQL 容器 4. 进入 MySQL 容器,登陆 MySQL 5. 远程登陆 MySQL 6. 查看容器 IP 地址 二、tomcat 部署 1. 拉取 tomcat 镜像 2. 创建 tomcat 容器 3. 搭建 Tomcat 服务并部署 web 应用 三、Nginx 部署 …

别名路径联想设置

如何使用/进行路径提示? 找到jsconfig.json文件,如何项目中没有的话,自行创建 {"compilerOptions": {"paths": {"/*": ["./src/*"]}},"exclude": ["node_modules", "dis…

osi七层模型

文章目录 1、网络层1、数据链路层2、以太网和mac地址3、地址解析协议(arp)1、免费arp 4、物理层1、双绞线(网线) 5、总结 1、网络层 路由器就是网络层设备,因为是根据目标ip报文来实现转发的,三层的 1、数据链路层 作用 解决了,ip报文在链路…

spark (算子 ) groupBykey+Map 和 reduceBykey 的区别

1)面试题:groupByKeymap和reduceByKey都能实现分布式分组聚合,有什么区别? - groupByKey没有Map端聚合的操作,只做分组,必须等分区结束才能实现,最终map需要做整体聚合 - reduceByKey是有Map端聚…