当前位置: 首页 > news >正文

云服务器里面做网站播放器/成都全网推广哪家专业

云服务器里面做网站播放器,成都全网推广哪家专业,营销型网站建设域名,网上商城网站设计和实现目录 一、JVM内存区域划分 ①程序计数器(每个线程都有一个) ②栈:保存了局部变量和方法调用的信息(每一个线程都有一个栈) 如果不停地调用方法却没有返回值,会产生什么结果 ③堆(每一个进程都有一个堆,线程共享一个堆) 如何区分一个变量是…

目录

一、JVM内存区域划分

①程序计数器(每个线程都有一个)

②栈:保存了局部变量和方法调用的信息(每一个线程都有一个栈)

       如果不停地调用方法却没有返回值,会产生什么结果

③堆(每一个进程都有一个堆,线程共享一个堆)

       如何区分一个变量是处于栈上还是堆上呢?

④方法区(存放的是类对象)

类对象是什么

二、类加载机制

步骤1:Loading

步骤2:Linking(验证、准备、解析)

①验证:验证Class文件是否符合规范

②准备:给静态变量分配内存

 ③解析:初始化类的常量池当中的一些常量

步骤3:初始化(初始化对象,为静态属性赋值) 

双亲委派机制

双亲委派模型

JVM类加载器是什么(3个类加载器)

标准库的String类是怎样被加载的

自定义的Test类是怎加加载的

双亲委派模型的好处

 类加载一定要双亲委派模型吗


一、JVM内存区域划分

JVM的内存区域被划分为了以下4个部分:

程序计数器、栈、堆、方法区。

下面,将分别介绍这几个区是干什么的。


①程序计数器(每个线程都有一个)

       这一个区域是内存当中最小的区域。保存了下一条要执行的指令的地址在哪里。

       指令:就是字节码。程序要运行,JVM就得把字节码加载起来,存放到内存当中。

       当程序把一条条指令从内存当中取出来,放到CPU上面执行的时候,也需要随时记住执行到哪一条了(因为CPU是并发执行命令的,不是只给一个进程提供服务的)

       每一个线程都会有一个程序计数器。(因为操作系统是以线程为单位进行调度的)每一个线程都需要记录自己执行的位置。

     


②栈:保存了局部变量和方法调用的信息(每一个线程都有一个栈)

       当每调用一个新的方法的时候,都会涉及到"入栈"操作。每执行完一个方法的时候,就会把这一个方法从内存栈当中移除。

       当A方法内部调用B方法,然后在B方法内调用C方法的结果是怎样的呢?

       首先,会在内存栈当中存放A方法的有关信息。然后,调用B方法的时候,在栈中存放B方法的信息。最后调用C方法的时候,会在栈当中存放C方法有关的信息。

       此处,"有关的信息"有:方法的局部变量、方法传入的参数(形参)、调用的位置、返回的位置等等信息。

       当方法执行完毕(或者return)之后,方法对应的信息也会随之从内存栈上面消失。每一个存放方法的区域被称为一个"栈帧"。 

       如果不停地调用方法却没有返回值,会产生什么结果

        

         运行一下程序,可以发现:

         此处抛出了一个错误信息:StackOverflowError

        JVM的栈空间是比较小的,但是也就一般几M或者几十M,因此在上述的调用过程当中栈很有可能会满了的。 

          

对于栈来说,每一个线程都有一个栈。不同的线程有不同的栈


③堆(每一个进程都有一个堆,线程共享一个堆)

       堆是内存内存空间当中最大的区域。new出来的对象,就是在堆当中的。那么也就意味着,对象的成员变量也是存储在堆当中的。

       如何区分一个变量是处于栈上还是堆上呢?

        局部变量(也就是方法内部创建的基本数据类型变量)都存储在调用这个方法的线程的栈上。

        成员变量new出来的对象,都存放在堆上面。但是方法内部对于对象的引用是保存在栈上面的。


④方法区(存放的是类对象)

方法区当中,存放的是一个类的.class对象(二进制字节码)。

这里的这个class对象,就是保存在方法区当中的。

类对象是什么

      类对象描述的就是它对应类当中的属性、方法、以及各自的权限描述符。

      此外,一个类当中的static方法、static属性也是属于类对象的。这些方法、属性又被称为"类方法"、"类属性"


二、类加载机制

简单来说,就是把.class文件,加载到内存当中,构建类对象

类加载分为3个步骤:

步骤1:Loading

步骤2:Linking

步骤3:Initialization

下面,详细说明一下每一个步骤是干什么的: 


步骤1:Loading

       先找到对应的.class文件,然后打开并且读取.class文件。同时初步生成一个类对象(但是不是真正使用的对象)。

        1)通过一个类的全限定名来获取此类的二进制字节流

        2)将这个字节流所代表的静态存储结构转化为方法运行时候的数据结构

        3)在内存当中生成一个代表此类的java.lang.Class对象。然后把这个Class对象,放入到方法区当中,作为方法区这个类的各种数据的访问入口。

下面,来看一下这个二进制的.class文件究竟包含了什么。

下图就是一个ClassFile的图示。

其中,左边的u4代表的就是,u2等信息代表的是占了多少个字节。

u4就是4个字节的unsigned int。u2就是2个字节的unsigned int。


步骤2:Linking(验证、准备、解析)

由上图,也可以看到在连接部分分为了三个步骤:验证准备解析

首先,看一下"验证"这个部分是做什么的


①验证:验证Class文件是否符合规范

         确保Class文件字节流中包含的信息符合《Java虚拟机规范》的全部约束要求。如果想读取Class文件的内容,就需要先验证一下是否符合规范。验证的内容有:

    文件格式验证;

    字节码验证;

    符号引用验证。


②准备:给静态变量分配内存

例如,给static修饰的变量分配内存,并且设置上初始的值:也就是默认值。

例如下面的代码当中,有一个属性为id,它被static修饰,并且它的值为123。

但是在现在这个阶段,它真实的值还是0。

class Member{private static int id=123;private String name;
}

 ③解析:初始化类的常量池当中的一些常量

       在前面我们也提到了,.class文件当中包含了一些常量,每一个常量都有一个编号。那么这个时候,就是初始化一些常量的时候了。


步骤3:初始化(初始化对象,为静态属性赋值) 

       此时,就是针对对象进行初始化的操作,在这一步的基础上产生对象。

       同时,在这一个步骤上,会把静态的变量给赋值上它对应的值。

       例如在前面的时候,提到了在准备阶段,为一个静态的变量赋上默认的值。但是并没有为它赋值上真正的值。那么就是在初始化的阶段为它赋值上真正的值。


双亲委派机制

首先,先来体验一下双亲委派机制。

让一个类B继承自A。然后在A这个类当中包含以下几个内容:

A的构造方法、一个构造代码块、一个静态代码块。

 然后,让B继承自A,在B这个类的内部,包含以下的几个内容:

B的构造方法、B的构造代码块、B的静态代码块。

       最后,令一个Test类继承自B类,并且在Test类当中包含一个mian方法。main方法当中连续两次调用new Test()。

class A {public A() {System.out.println("A的构造方法");}{System.out.println("A的构造代码块");}static {System.out.println("A的静态代码块");}
}class B extends A {public B() {System.out.println("B的构造方法");}{System.out.println("B的构造代码块");}static {System.out.println("B的静态代码块");}}/*** @author 25043*/
public class Test1 extends B {public static void main(String[] args) {System.out.println("第一次new");new Test1();System.out.println("第二次new");new Test1();}
}

  运行之后,结果是:

根据以上的特点,可以得出来,双亲委派机制加载类实例的几个原则:

1、类加载首先需要加载静态的代码块:先父类静态代码块,然后子类静态代码块

2、静态代码块只会在类加载的时候执行1次。若重复加载(重复new对象)那么只会执行一次。

3、构造代码块和构造方法每一次new都会执行。并且构造代码块一定优先于构造方法执行。

4、无论是静态还是实例代码块,一定都是父类子类之前。 

总结一下,那就是:

静态优先且唯一、父类优先、代码块优先。 


为什么在输出"第一次new"之前,先输出了"第一次加载A"和"第一次加载B"呢?

       因为:如果想要执行main方法,首先需要加载Test类。但是由于Test继承于B类,然后B类又继承于A类。因此,会首先加载顶级父类A的静态代码块,然后再加载下一级父类的静态代码块。


双亲委派模型

在上面的文章当中,我们提到了,类的加载分为3个阶段:

 第一阶段:Loading阶段;

 第二阶段:Linking阶段;

 第三阶段:Initialing阶段。

        Loading阶段,主要负责的就是加载一个类的字节码文件,并生成一个Class对象

       而双亲委派模型,描述的是JVM当中的类加载器,如何根据全限定名:类名+包名(例如Java.lang.String)找到.class文件的过程,这个过程属于Loading阶段当中比较靠前的阶段。

       


JVM类加载器是什么(3个类加载器)

JVM的类加载器主要是以下的3个:

1、BootStarpClassLoader:负责加载标准库当中的类(例如String、List等等)

2、ExtensionClassLoader:负责加载JDK当中的扩展类

3、ApplicationClassLoader:负责加载当前目录当中的类。

每一个类加载器负责加载自己对应的目录。 

 而上述的双亲委派模型,就描述了找目录的过程,上述3个类加载器是怎样进行配合的。


下面,举一个例子:

标准库的String类是怎样被加载

       第一步:程序启动,先进入ApplicationClassLoader类加载器。

       第二步:然后在ApplicationClassLoader当中检查一下,它的父加载器(ExtensionClassLoader)是否已经加载过了。如果没有加载过,那么就调用ExtensionClassLoader来进行加载。

       第三步:ExtensionClassLoader也会检查一下,它的父加载器(BootStarpClassLoader),是否加载过。如果没有,那么就调用最高的父加载器(BootStarpClassLoader)来进行加载。

       然后查找标准库的目录:Java.lang.String,并且完成Java.lang.String的加载。


自定义的Test类是怎加加载的

       自定义的Test类,也会经过上述

       由ApplicationClassLoader==>ExtensionClassLoader==>BootStrapClassLoader的三个加载过程。

       但是,由于BootStrapClassLoader负责的目录是标准库的目录,那么肯定找不到Test类,于是回到下一级的目录:ExtensionClassLoader进行加载。同样,也找不到Test类。最后,回到ApplicationClassLoader负责的目录,也就是当前项目的目录进行加载,最终找到了Test类,进行加载。

 如果在最后的阶段,也没有找到Test类,那么就会抛出一个异常:ClassNotFoundException


双亲委派模型的好处

       当用户自定义的类如果和派生类/标准库当中的类如果全限定名(类名称+包名称)重复了,仍然可以准确地加载标准库当中的类,而不是加载用户自定义的类    

       在上述过程当中,如果查找到标准库当中有Java.lang.String这个类,就不会再回去加载了

       此处,我自定义一个类(java.lang.String)

 但是,如果在其他的地方进行new,发现new的是标准库当中的类。  


 类加载一定要双亲委派模型吗

       不一定,双亲委派模型只是JVM内部实现的一个类加载机制。

       例如Tomcat加载webapps当中的类就没有使用双亲委派模型,因为Tomcat当中的类都是已经被开发好了的,无需多一道从标准库回去查询的工序。

       双亲委派模型只是避免用户自定义的类标准库当中的类全限定名重名时候,加载了用户的类。但是如果已经确定了用户自定义的类的全限定名和标准库的不一致,那么就没有必要多去检验一次父加载器当中是否有加载了。


 

 

 

相关文章:

【JVM篇1】认识JVM,内存区域划分,类加载机制

目录 一、JVM内存区域划分 ①程序计数器(每个线程都有一个) ②栈:保存了局部变量和方法调用的信息(每一个线程都有一个栈) 如果不停地调用方法却没有返回值,会产生什么结果 ③堆(每一个进程都有一个堆,线程共享一个堆) 如何区分一个变量是…...

CHAPTER 5 文件共享 - FTP

文件共享 - FTP1 FTP1.1 传输方式1. ASCII传输方式2. 二进制传输模式3. 两种传输方式的区别1.2 支持的模式1. 主动模式(PORT)2. 被动模式(PASV)3. 如何选择4. 为什么绝大部分互联网应用都是被动模式?1.3 搭建FTP服务器(使用vsftpd)1. 安装软件…...

【MySQL】将 CSV文件快速导入 MySQL 中

【MySQL】将 CSV文件快速导入 MySQL 中方法一:使用navicat等软件的导入向导如果出现中文乱码方法二:命令行导入(LOAD DATA INFILE SQL)一般来说,将csv文件导入mysql数据库有两种办法: 使用 navicat、workbe…...

Ngnix安装教程(2023.3.8)

Nginx安装教程(2023.3.8)引言1、Nginx简介2、Nginx安装2.1 下载Nginx安装包2.2 免安装启动Nginx(切记解压后将nginx-1.23.3文件夹需要放在英文路径下,实测中文路径不识别且启动不成功)2.3 熟悉Nginx文件夹目录结构2.4 …...

【C语言】每日刷题 —— 牛客(2)

前言 大家好,继续更新专栏c_牛客,不出意外的话每天更新十道题,难度也是从易到难,自己复习的同时也希望能帮助到大家,题目答案会根据我所学到的知识提供最优解。 🏡个人主页:悲伤的猪大肠9的博客…...

关于算法的一些简单了解

文章目录ALGORITHMBASIC INFORMATIONBasic algorithm design technology穷举法分治法减治法动态规划法贪心法Algorithm design technology based on search回溯法分支限界法PRACTICECONCEPTCALATION*CODEprim&dijkstra&kruskal分治法Q&AT(n)T(n)T(n) 是渐进时间复杂…...

mysql无法启动服务及其他问题总结

文章目录1.安装后关于配置的问题显示【发生系统错误,拒绝访问】命令行Command Line Client闪退2.显示【MySQL服务无法启动】问题检查端口被占用删除data文件并初始化配置my.ini/.conf文件重新安装MySQL1.安装后关于配置的问题 显示【发生系统错误,拒绝访…...

数据库表字段命名规范

因为近期笔者在数据库命名规范上产生了一些疑问,故特此记录下来了一些开发规范,望做参考。 摘要: 当前研发工作中经常出现因数据库表、数据库表字段格式不规则而影响开发进度的问题,在后续开发使用原来数据库表时,也会…...

23种设计模式-命令模式(android应用场景介绍)

命令模式是一种行为设计模式,它允许将请求封装成一个独立的对象,并将请求的不同参数化。通过这种方式,命令模式可以在不同的请求间切换,或者将请求放入队列中等待执行。 在Java中,命令模式通常由一个抽象命令类和具体…...

vector你得知道的知识

vector的基本使用和模拟实现 一、std::vector基本介绍 1.1 常用接口说明 std::vector是STL中的一个动态数组容器,它可以自动调整大小,支持在数组末尾快速添加和删除元素,还支持随机访问元素。 以下是std::vector常用的接口及其说明&#xf…...

【C++进阶】四、AVL树(二)

目录 前言 一、AVL树的概念 二、AVL树节点的定义 三、AVL树的插入 四、AVL树的旋转 4.1 左单旋 4.2 右单旋 4.3 左右双旋 4.4 右左双旋 五、AVL树的验证 六、AVL树的性能 七、完整代码 前言 前面对 map/multimap/set/multiset 进行了简单的介绍,在其文…...

React 服务端渲染

React 服务器端渲染概念回顾什么是客户端渲染CSR(Client Side Rendering)服务器端只返回json数据,Data和Html的拼接在客户端进行(渲染)。什么是服务器端渲染SSR(Server Side Rendering)服务器端返回数据拼接过后的HTML,Data和Html…...

【算法设计-搜索】回溯法应用举例(1)

文章目录0. 回溯模板1. 走楼梯2. 机器走格子,但限定方向3. 中国象棋,马走日字4. 走迷宫5. 积木覆盖0. 回溯模板 搜索算法中的回溯策略,也是深度优先搜索的一种策略,比较接近早期的人工智能。毕竟,搜索是人工智能技术中…...

C++基础了解-23-C++ 多态

C 多态 一、C 多态 多态按字面的意思就是多种形态。当类之间存在层次结构,并且类之间是通过继承关联时,就会用到多态。 C 多态意味着调用成员函数时,会根据调用函数的对象的类型来执行不同的函数。 下面的实例中,基类 Shape 被…...

【GNN/深度学习】常用的图数据集(资源包)

【GNN/深度学习】常用的图数据集(图结构) 文章目录【GNN/深度学习】常用的图数据集(图结构)1. 介绍2. 图数据集2.1 Cora2.2 Citeseer2.3 Pubmed2.4 DBLP2.5 ACM2.6 AMAP & AMAC2.7 WIKI2.8 COCS2.9 BAT2.10 EAT2.11 UAT2.12 C…...

Clickhouse中bitmap介绍以及计算留存Demo

前言 参考了腾迅的大数据分析-计算留存,能够根据用户自定义属性,以及玩家行为进行留存的计算。最初计算留存的方法使用的是clickhosue自带的rentention函数,使用这个函数不用关注太多细节,只需要把留存条件放入函数即可。但是这个如果需要关联用户属性,就比较麻烦了。因此…...

大数据是什么?学习后能找高薪工作么

大数据是什么,比较官方的定义是指无法在一定时间范围内用常规软件工具进行捕捉、管理和处理的数据集合,是需要新处理模式才能具有更强的决策力、洞察发现力和流程优化能力的海量、高增长率和多样化的信息资产。 简单来说,大数据就是结构化的…...

如何提取视频中的音频转文字?分享提效减负视频转文字方法

最近我在学做短视频,就看了很多博主怎么做视频,像他们的拍摄方法、剪辑角度还有怎么写文案。我一开始只看了一两个博主,写文案时就是边看视频边打字,这视频量少还好,视频多了就觉得这种方法好费时间,感觉一…...

脑机接口科普0018——前额叶切除手术

本文禁止转载!!! 首先说明一下,前额叶切除手术,现在已经不允许做了。 其次,前额叶切除手术,发明这个手术的人居然还获得了诺贝尔奖。太过于讽刺。1949年的那次诺贝尔医学奖(就是我…...

FPGA工程师面试——基础知识

1. 简述FPGA等可编程逻辑器件设计流程 答:系统设计电路构思,设计说明与设计划分, 电路设计与输入(HDL代码、原理图), 功能仿真与测试, 逻辑综合, 门级综合, 逻辑验证与测…...

全国青少年软件编程(Scratch)等级考试一级真题——2019.12

青少年软件编程(Scratch)等级考试试卷(一级)分数:100 题数:37一、单选题(共25题,每题2分,共50分)1.下列关于舞台的描述,不正确的是?( &#xff09…...

【Integrated Electronics系列——数字电子技术基础】

目录 序言...

【微信小程序】-- 页面处理总结(三十一)

💌 所属专栏:【微信小程序开发教程】 😀 作  者:我是夜阑的狗🐶 🚀 个人简介:一个正在努力学技术的CV工程师,专注基础和实战分享 ,欢迎咨询! &…...

Spring Batch使用详细例子

Spring Batch 是一个开源的批处理框架,它提供了一种简单的方式来处理大规模的数据处理任务。它基于 Spring 框架,可以与 Spring 的其他组件无缝集成,如 Spring Boot、Spring Data 等。本文将介绍如何使用 Spring Batch 进行批处理任务。 1. 准…...

漏洞预警|Apache Dubbo 存在反序列化漏洞

棱镜七彩安全预警 近日网上有关于开源项目Apache Dubbo 存在反序列化漏洞,棱镜七彩威胁情报团队第一时间探测到,经分析研判,向全社会发起开源漏洞预警公告,提醒相关安全团队及时响应。 项目介绍 Apache Dubbo 是一款 RPC 服务开…...

Tomcat源码分析-spring boot集成tomcat

SPI 在分析源码前,我们先来了解下 spring 的 SPI 机制。我们知道,jdk 为了方便应用程序进行扩展,提供了默认的 SPI 实现(ServiceLoader),dubbo 也有自己的 SPI。spring 也是如此,他为我们提供了…...

一个古老的html后台的模板代码

效果图下: css部分代码:/* CSS Document / body{font-family:“宋体”, Arial,Verdana, sans-serif, Helvetica;font-size:12px;margin:0;background:#f4f5eb;color:#000;} dl,ul,li{list-style:none;} a img{border:0;} a{color:#000;} a:link,a:visit…...

支持向量回归删除异常值Python

1、支持向量回归(SVR)原理 支持向量回归(Support Vector Regression,SVR)不仅可以用于预测,还可以用于异常值检测。其基本思路是训练一个回归模型,通过对每个数据点进行预测,并计算…...

手把手开发一门程序语言JimLang (2)

根据爱因斯坦的相对论,物体的质量越大,时间过得越快,所以托更对于我的煎熬,远远比你们想象的还要痛苦…今天给大家来盘硬菜,也是前些时日预告过的JimLang的开发过程… Let’s go !!! 语法及解析 JimLang.g4 这里我们…...

DSF深度搜索时到底是如何回溯的(小tip)

这一段让我迷了两次,为什么回溯的时候,恢复了最后一位,往上递归一层之后,把最后一位填在它前一位,但是原本的前一位没有恢复,最后一位要怎么办?其实这还是递归没明白 也就是这一步是如何实现的 …...