第三章 JVM内存概述

news2024/9/27 22:08:32

附录:精选面试题

Q:为什么虚拟机必须保证一个类的Clinit( )方法在多线程的情况下被同步加锁 ?

A: 因为虚拟机在加载完一个类之后直接把这个类放到本地内存的方法区(也叫原空间)中了,当其他程序再来调这个类的时候直接从内存中拿的,因此Clinit( )方法只会执行一次来保证类只会被加载一次,当同时有两个线程进来操作同一个类的Clinit( )方法,可能会出现数据的不一致性,当两个线程中的某个线程抢到了类锁,而且一直在Clinit()方法中执行,另一个线程会一直保持阻塞状态

Q: 类加载子系统中的加载阶段分别有哪些类加载器 ?

A: 一般会有BootStarpClassLoader引导类加载器,ExtClassLoader扩展类加载器,ApplicationClassLoder应用类加载器。

Q: 类加载器又分为几种 ?

A: 从官方给的规范来讲,分为两种类加载器,分别是引导类加载器,和自定义类加载器。引导类加载器BootStarpClassLoader是由C语言和C++进行编写的,主要加载Java的核心类库。而直接或间接继承ClassLoader的加载器都可以认为是自定义类加载器,JVM默认提供给用户使用的是继承图最底层的ApplicationClassLoader系统类加载器,ApplicationClassLoader调用getParent( )方法一直往上面调,是获取不到BootStarpClassLoader引导类加载器的

一、内存结构

当class文件以二进制流的方式加载到JVM内存的类加载子系统时,在类加载子系统(Class Loader SubSystem)中又分三步对数据进行解析,分别是加载阶段(Lading),链接阶段(Linking),初始化阶段(Initiatlizetion)。

加载阶段有:引导类加载器(BootStrapClassLoader),扩展类加载器(ExtensionClassLoder),系统类加载器(ApplicationClassLoder),和自定义加载器。

链接阶段:验证(Verify),准备(Prepare),解析(Resolve)。

最后把数据一起放入初始化阶段

二、类加载器和类加载过程

ClassLoader 只负责class文件的加载,至于是否可以运行,则有ExecutionEngin(执行引擎) 决定。

Loading加载阶段

链接阶段(Linking)

初始化阶段(Initiatlizetion)

程序加载到初始化阶段<clinit>( )方法会收集静态变量赋值的动作,在连接阶段(Linking)先为静态变量(类变量)赋0值,当程序走到初始化阶段从上到下收集赋值动作,赋值给静态变量。

当类中没有声明过静态变量或者静态代码块时,类加载子系统在进行到初始化阶段时就不会创建<clinit>( )方法。

变量声明在静态代码块的后面,可以在静态代码块进行赋值,但不能进行调用,报错信息为 “非法的前向引用”

任何一个类都会有 init( )方法(用来初始化类对象),但都有Clinit( )方法(用于收集静态变量,供该类全局使用)

Q:为什么虚拟机必须保证一个类的Clinit( )方法在多线程的情况下被同步加锁。

A: 因为虚拟机在加载完一个类之后直接把这个类放到本地内存的方法区(也叫原空间)中了,当其他程序再来调这个类的时候直接从内存中拿的,因此Clinit( )方法只会执行一次来保证类只会被加载一次,当同时有两个线程进来操作同一个类的Clinit( )方法,可能会出现数据的不一致性,当两个线程中的某个线程抢到了类锁,而且一直在Clinit()方法中执行,另一个线程会一直保持阻塞状态。

三、类加载器的分类

下面这一张图的几种类加载器是等级关系,例如文件目录上下级。但绝不能理解为是 继承关系。BootClassLoader是用C和C++编写的,而下面的几个类加载器是Java语言编写的,都间接继承了ClassLoader。

是一种像文件夹一样的包含关系。A文件夹包含B文件夹,B文件夹又包含着C文件夹,ClassLoader.getSystemClassLoader( ) 方法获取到ApplicationClassLoader。

也可以认为BootStarpClassLoader只负责加载Java程序的核心类库,自定义的加载器太low了,不配“高端”加载器出手帮忙,另外一方面,BootStarpClassLoader是使用C和C++进行编写的,自热而然的就获取不到它的对象了。

public class ClassLoaderTest {
    public static void main(String[] args) {

        //获取系统类加载器
        ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
        System.out.println(systemClassLoader);//sun.misc.Launcher$AppClassLoader@18b4aac2

        //获取其上层:扩展类加载器
        ClassLoader extClassLoader = systemClassLoader.getParent();
        System.out.println(extClassLoader);//sun.misc.Launcher$ExtClassLoader@1540e19d

        //获取其上层:获取不到引导类加载器
        ClassLoader bootstrapClassLoader = extClassLoader.getParent();
        System.out.println(bootstrapClassLoader);//null

        //对于用户自定义类来说:默认使用系统类加载器进行加载
        ClassLoader classLoader = ClassLoaderTest.class.getClassLoader();
        System.out.println(classLoader);//sun.misc.Launcher$AppClassLoader@18b4aac2

        //String类使用引导类加载器进行加载的。---> Java的核心类库都是使用引导类加载器进行加载的。
        ClassLoader classLoader1 = String.class.getClassLoader();
        System.out.println(classLoader1);//null


    }
}

引导类、扩展类、系统类加载器的使用及演示

引导类加载器

在上面我们看到,从最底层的systemClassLoader系统类加载器,调用 getParent( )方法会调用到它上层的一个扩展类加载器和应用类加载器对象,这些两个类加载器对象也都需要加载。都是通过BootStarpClassLoader引导类加载器进行加载的,所以也就把BootStarpClassLoader、ExtClassLoader、ApplicationClassLoader都认为是系统核心类库。

扩展类加载器扩展类加载器扩展类加载器扩展类加载器扩展类加载器扩展类加载器扩展类加载器扩展类加载器扩展类加载器扩展类加载器

应用程序类加载器应用程序类加载器应用程序类加载器应用程序类加载器应用程序类加载器应用程序类加载器应用程序类加载器应用程序类加载器应用程序类加载器应用程序类加载器

自定义类加载器自定义类加载器自定义类加载器自定义类加载器自定义类加载器

自定义加载器

package com.atguigu.java1;

import java.io.FileNotFoundException;

/**
 * 自定义用户类加载器
 * @author shkstart
 * @create 2019 下午 12:21
 */
public class CustomClassLoader extends ClassLoader {
    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {

        try {
            byte[] result = getClassFromCustomPath(name);
            if(result == null){
                throw new FileNotFoundException();
            }else{
                return defineClass(name,result,0,result.length);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

        throw new ClassNotFoundException(name);
    }

    private byte[] getClassFromCustomPath(String name){
        //从自定义路径中加载指定类:细节略
        //如果指定路径的字节码文件进行了加密,则需要在此方法中进行解密操作。
        return null;
    }

    public static void main(String[] args) {
        CustomClassLoader customClassLoader = new CustomClassLoader();
        try {
            Class<?> clazz = Class.forName("One",true,customClassLoader);
            Object obj = clazz.newInstance();
            System.out.println(obj.getClass().getClassLoader());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
package com.atguigu.java1;

/**
 * @author shkstart
 * @create 2020 上午 10:59
 */
public class ClassLoaderTest2 {
    public static void main(String[] args) {
        try {
            //1.获取引导类加载器 获取不到 null
            ClassLoader classLoader = Class.forName("java.lang.String").getClassLoader();
            System.out.println(classLoader);
            //2.获取系统类加载器  sun.misc.Launcher$AppClassLoader@18b4aac2
            ClassLoader classLoader1 = Thread.currentThread().getContextClassLoader();
            System.out.println(classLoader1);

            //3.获取扩展类加载器  sun.misc.Launcher$ExtClassLoader@1b6d3586
            ClassLoader classLoader2 = ClassLoader.getSystemClassLoader().getParent();
            System.out.println(classLoader2);

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

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

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

相关文章

vue2.0中使用summernote富文本编辑器, 并实现上传图片至七牛

vue2.0中使用summernote富文本编辑器, 并实现上传图片至七牛 ackage.json 文件中添加所需的依赖库,然后执行 npm install 安装这些库 2. 在 src / main.js 文件中导入下列库文件 3. 由于summernote 使用 jQuery 库, 我们在组件里需要导入 jQuery才能使用, 为了方便起见,我们在 …

《深入理解计算机系统(CSAPP)》第7章 链接 - 学习笔记

写在前面的话&#xff1a;此系列文章为笔者学习CSAPP时的个人笔记&#xff0c;分享出来与大家学习交流&#xff0c;目录大体与《深入理解计算机系统》书本一致。因是初次预习时写的笔记&#xff0c;在复习回看时发现部分内容存在一些小问题&#xff0c;因时间紧张来不及再次整理…

chatgpt赋能python:Python中安装nio和ngl

Python中安装nio和ngl 介绍 nio和ngl是Python中用于网络编程和HTTP协议的模块。它们可以帮助开发人员快速地创建网络应用程序和RESTful API。 nio扩展了Python的Socket模块&#xff0c;并提供了一组高级的网络编程接口&#xff0c;比如异步IO和事件驱动编程。ngl则提供了一组…

就业内推 | 国企、运营商有岗,CCNP以上

01 中电鸿信信息科技有限公司 &#x1f537;招聘岗位&#xff1a;网络工程师 &#x1f537;职责描述&#xff1a; 1.主要负责云网类项目的网络方案规划、评审、集成交付及参照相关集成标准对硬件集成商交付的资源池基础网络进行验收&#xff1b; 2.完成公司交办的其他工作&am…

chatgpt赋能python:Python中如何根据值提取键

Python中如何根据值提取键 在编程中&#xff0c;我们经常需要在Python中查找一个字典中的值&#xff0c;然后返回它的键。这种操作在各种应用程序中经常被使用&#xff0c;例如数据库&#xff0c;社交媒体应用程序或者网上商店。 在Python中&#xff0c;这个过程非常简单&…

chatgpt赋能python:Python中如何优雅地分行

Python中如何优雅地分行 Python是一门优雅而又简洁的编程语言&#xff0c;它没有繁琐的语法规则和冗余的表达式。然而&#xff0c;随着程序规模的增大&#xff0c;代码行数也随之增多。为了使代码更加易读和易维护&#xff0c;良好的代码分行是必不可少的。 在Python中&#…

Python安全和防护:如何保护Python应用程序和用户数据的安全

章节一&#xff1a;引言 在当今数字化时代&#xff0c;数据安全是一个极其重要的话题。随着Python的广泛应用和越来越多的人使用Python构建应用程序&#xff0c;保护Python应用程序和用户数据的安全变得尤为重要。本文将介绍一些关键的Python安全问题&#xff0c;并提供一些保…

如何提高AI绘画的出图质量?

先上几张本人随便跑的图&#xff0c;虽说算不上多惊艳&#xff0c;但也是什么都不设置达不到的效果。文末附上本人常用的一些优质大模型。 本人不喜欢细枝末节讲一堆&#xff0c;以下只说重点&#xff0c;如果有一些名词及操作不明白&#xff0c;可以去查对应资料&#xff08;应…

移动端布局之流式布局1(百分比布局)

移动端布局之流式布局1 流式布局&#xff08;百分比布局&#xff09;基础案例&#xff1a;京东移动端首页搭建相关文件夹结构设置视口标签以及引入初始化样式normalize.css引入我们的css初始化文件与首页css body设置index.css app布局和app内容填充index.htmlindex.css 搜索模…

python+django+vue协同过滤算法的电影推荐评分系统nzf73

用户:登录&#xff0c;注册&#xff0c;修改密码&#xff0c;修改个人信息&#xff0c;电影搜索&#xff0c;电影评分&#xff0c;电影评论&#xff0c; 推荐:个性化推荐电影(协同过滤)&#xff0c;热门推荐 管理员:用户管理&#xff0c;电影管理&#xff0c;评论管理 电影是本…

chatgpt赋能python:Python中同一个类中方法互相调用的意义

Python中同一个类中方法互相调用的意义 在Python中&#xff0c;类是一个非常重要的编程概念。类是由属性和方法组成的&#xff0c;其中方法是类中非常重要的部分。在类中的方法中&#xff0c;有时候我们需要调用其他方法。在本文中&#xff0c;我们将讨论Python中同一个类中方…

Leetcode11 盛最多水的容器

Leetcode11 盛最多水的容器 来源&#xff1a;力扣&#xff08;LeetCode&#xff09; 链接&#xff1a;https://leetcode.cn/problems/container-with-most-water/description 博主Github&#xff1a;https://github.com/GDUT-Rp/LeetCode 题目&#xff1a; 给定一个长度为 n…

科技创新盛典:全国科技者工作日激荡创新思维

⭐ 全国科技工作者日的由来⭐ 全国科技工作者日LOGO⭐ 科技工作者界定⭐ 历年主题⭐ 2023年全国科技工作者日 今天我要和大家分享一个令人激动和振奋的消息——全国科技者工作日&#xff01;这是一个特殊的日子&#xff0c;为我们所有投身于科技创新的人们而设立&#xff0c;让…

Linux更改SSH端口,并解决SSHD服务重启失败的问题

环境&#xff1a;Linux Centos 7 1.进入sshd配置文件&#xff1a;vi /etc/ssh/sshd_config 2、找到“#Port 22”这行&#xff0c;删掉注释符#&#xff0c;将端口改为&#xff08;想要变成的端口号 如&#xff1a;2022&#xff09;&#xff1a; 3.重启sshd服务&#xff1a; sy…

【C++】程序的内存模型 - 内存四区代码区,全局区,栈区,堆区,new运算符

文章目录 1. 程序运行前1.1 代码区1.2 全局区 2. 程序运行后2.1 栈区2.2 堆区 3. new运算符 本阶段开始主要针对C面向对象编程技术&#xff0c;探讨C中的核心和精髓。 C程序在执行时&#xff0c;将内存大方向划分为4个区域&#xff1a; 代码区&#xff1a;存放函数体的二进制…

chatgpt赋能python:Python中拼接字符串的最佳方法

Python中拼接字符串的最佳方法 在Python编程中&#xff0c;拼接字符串是一个非常常见的任务。无论是将多个字符串连接成一个字符串&#xff0c;还是将变量值插入到字符串中&#xff0c;我们都需要拼接字符串。本文将介绍Python中拼接字符串的几种方法&#xff0c;并为你推荐最…

Vue登录界面精美模板分享

文章目录 &#x1f412;个人主页&#x1f3c5;Vue项目常用组件模板仓库&#x1f4d6;前言&#xff1a;&#x1f380;源码如下&#xff1a; &#x1f412;个人主页 &#x1f3c5;Vue项目常用组件模板仓库 &#x1f4d6;前言&#xff1a; 本篇博客主要提供vue组件之登陆组件源码…

车辆CAN信号,依据DBC文件解析流程

CAN信号解析流程 1.车辆CAN对应dbc文件 DBC文件是一种用于描述CAN&#xff08;Controller Area Network&#xff09;数据通信协议的文件格式&#xff0c;DBC文件中包含了CAN数据的信号定义、编码方式、单位、范围等信息&#xff0c;可以用于解析和生成CAN数据帧。 一个DBC文件…

数据结构与算法06:递归和简单的排序

目录 【递归】 【排序】 冒泡排序 插入排序 选择排序 【每日一练&#xff1a;K 个一组翻转链表】 【递归】 递归是将一些有规律的重复问题分解为同类的子问题的方法&#xff0c;也就是在函数中自己调用自己。比较经典的递归代码就是 斐波那契数列&#xff0c;实现方式如…

特征选择及特征提取

特征 什么是特征&#xff1a; 举个例子&#xff1a;一个妹子很好看&#xff0c;好看的在哪里&#xff1f;腿长&#xff08;特征1&#xff09;&#xff0c;白&#xff08;特征2&#xff09;&#xff0c;性格开朗&#xff08;特征3&#xff09; 那么可以概括为好看妹子的特征是…