面试被怼?还搞不懂JVM?阿里架构师带你掌握JVM类加载机制

工作3年进阿里,取得P7职位,需要怎样的技术能力?(面试题附答案) 前言 好多人对阿里巴巴技术岗的体系结构及级别的技术要求设置不太清楚,想去面试也不知道面试什么级别的岗位。下面说说阿里P7技术体系是一个需要怎么样的技术能力。 先来看看P7需要的能力: 阿里P7(技术主管) 工作要求: 技能要求: 1、3年以上专职Java开发经验,擅长分布式系统设计和应用开发,熟悉分布式、缓存、消息、RPC、反射、类加载、JVM等底层运行机制,具备高并发系统的独立实现和性能调优经验,熟练掌握Spring boot/Spring cloud等框架,熟练掌握mybatis/ibatis的应用技巧 阅读详情

本文转载自:面试被怼?还搞不懂JVM?阿里架构师带你掌握JVM类加载机制


一、类的生命周期

类的生命周期包含下面7个阶段,其中前五步属于类加载阶段:

  • 加载
  • 验证
  • 准备
  • 解析
  • 初始化
  • 使用
  • 卸载

二、类加载阶段

1. 加载

加载阶段,虚拟机做了以下3件事情:

  1. 通过一个类的全限定名来获取定义此类的二进制字节流;
  2. 将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构
  3. 在内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口

简单一句话概括:把代码数据加载到内存中,加载完成后,在方法区实例化一个对应的Class对象。

延伸知识点

相对于类加载过程的其他阶段,一个非数组类的加载阶段(准确地说,是加载阶段中获取类的二进制字节流的动作)是开发人员可控性最强的,因为加载阶段既可以使用系统提供的引导类加载器来完成,也可以由用户自定义的类加载器去完成,开发人员可以通过定义自己的类加载器去控制字节流的获取方式(即重写一个类加载器的loadClass()方法)。

对于数组类而言,情况就有所不同,数组类本身不通过类加载器创建,它是由Java虚拟机直接创建的。但是数组类的元素类型(Element Type,指的是数组去掉所有维度的类型)最终是要靠类加载器去创建,如果数组的组件类型不是引用类型(例如int[]数组),Java虚拟机将会把数组C标记为与引导类加载器关联。

数组类的可见性与它的组件类型的可见性一致,如果组件类型不是引用类型,那数组类的可见性将默认为public。

2. 验证

当 JVM 加载完 Class 字节码文件并在方法区创建对应的 Class 对象之后,JVM 便会启动对该字节码流的校验,只有符合 JVM 字节码规范的文件才能被 JVM 正确执行。这个校验过程大致可以四个阶段:

  • 文件格式验证:是否以魔法数0xCAFEBABE开头、常量池的常量中是否有不被支持的常量类型等等。该验证阶段的主要目的是保证输入的字节流能正确地解析并存储于方法区之内,格式上符合描述一个Java类型信息的要求。这阶段的验证是基于二进制字节流进行的,只有通过了这个阶段的验证后,字节流才会进入内存的方法区中进行存储。只有通过了这个阶段的验证后,字节流才会进入内存的方法区中进行存储,所以后面的3个验证阶段全部是基于方法区的存储结构进行的,不会再直接操作字节流。
  • 元数据验证
  • 字节码验证
  • 符号引用验证

后面三个阶段可以归纳为代码逻辑校验,JVM 会对代码组成的数据流和控制流进行校验,确保 JVM 运行该字节码文件后不会出现致命错误,比如final 是否合规、类型是否正确、静态变量是否合理等。

简单一句话概括:验证字节流信息符合当前虚拟机的要求,防止被篡改过的字节码危害JVM安全。

3. 准备

当完成字节码文件的校验之后,JVM 便会开始为类变量分配内存并设置类变量初始值。

类变量是被 static 修饰的变量,准备阶段为类变量分配内存并设置初始值,使用的是方法区的内存。

实例变量不会在这阶段分配内存,它会在对象实例化时随着对象一起被分配在堆中。应该注意到,实例化不是类加载的一个过程,类加载发生在所有实例化操作之前,并且类加载只进行一次,实例化可以进行多次。

注意:这里的初始化指的是为变量赋予 Java 语言中该数据类型的零值,而不是用户代码里初始化的值。

简单一句话概括:为静态变量分配内存,并且设置默认值。

延伸知识点

这里举一个“特殊”知识点。

上面提到,在“通常情况”下初始值是零值,那相对的会有一些“特殊情况”:如果类字段的字段属性表中存在ConstantValue属性,那在准备阶段变量value就会被初始化为ConstantValue属性所指定的值,假设上面类变量value的定义变为:

public static final int value = 123;

在编译时Javac将会为被static和final修改的常量生成ConstantValue属性

编译时Javac将会为value生成ConstantValue属性,在准备阶段虚拟机就会根据ConstantValue的设置将value赋值为123。

为什么 static final 会直接被赋值?final 关键字在 Java 中代表不可改变的意思,意思就是说 value 的值一旦赋值就不会在改变了。既然一旦赋值就不会再改变,那么就必须一开始就给其赋予用户想要的值,因此被 final 修饰的类变量在准备阶段就会被赋予想要的值。而没有被 final 修饰的类变量,其可能在初始化阶段或者运行阶段发生变化,所以就没有必要在准备阶段对它赋予用户想要的值。

4. 解析

当通过准备阶段之后,JVM 针对类或接口、字段、类方法、接口方法、方法类型、方法句柄和调用点限定符 7 类引用进行解析。这个阶段的主要任务是将其在常量池中的符号引用替换成直接其在内存中的直接引用。

其中解析过程在某些情况下可以在初始化阶段之后再开始,这是为了支持 Java 的动态绑定。

简单一句话概括:解析类和方法,将常量池的符号引用替换为直接引用,确保类与类之间相互引用正确性,完成内存结构布局。

5. 初始化

类初始化阶段是类加载过程的最后一步,前面的类加载过程中,除了在加载阶段用户应用程序可以通过自定义类加载器参与之外,其余动作完全由虚拟机主导和控制。到了初始化阶段,才真正开始执行类中定义的Java程序代码(或者说是字节码)。

简单一句话概括:初始化阶段,执行类构造器<clinit>() 方法(类变量赋值、静态语句块),如果赋值运算是通过其他类的静态方法来完成的,那么会马上解析另外一个类,在虚拟机栈中执行完毕后通过返回值进行赋值。

<clinit>()方法是由编译器自动收集类中的所有类变量的赋值动作和静态语句块(static{}块)中的语句合并产生的,编译器收集的顺序由语句在源文件中出现的顺序决定。特别注意的是,静态语句块只能访问到定义在它之前的类变量,定义在它之后的类变量只能赋值,不能访问。例如以下代码:

public class Test {
    static {
        i = 0;                // 给变量赋值可以正常编译通过
        System.out.print(i);  // 这句编译器会提示“非法向前引用”
    }
    static int i = 1;
}

5.1 延伸知识点 - 父子类初始化顺序
由于父类的 () 方法先执行,也就意味着父类中定义的静态语句块的执行要优先于子类。例如以下代码:

static class Parent {
    public static int A = 1;
    static {
        A = 2;
    }
}

static class Sub extends Parent {
    public static int B = A;
}

public static void main(String[] args) {
     System.out.println(Sub.B);  // 2
}

5.2 延伸知识点 - 接口的初始化

接口中不可以使用静态语句块,但仍然有类变量初始化的赋值操作,因此接口与类一样都会生成 () 方法。但接口与类不同的是,执行接口的 () 方法不需要先执行父接口的 () 方法。只有当父接口中定义的变量使用时,父接口才会初始化。另外,接口的实现类在初始化时也一样不会执行接口的 () 方法。

5.3 延伸知识点 - 多线程同时初始化一个类

虚拟机会保证一个类的() 方法在多线程环境下被正确的加锁和同步。

如果多个线程同时初始化一个类,只会有一个线程执行这个类的 () 方法,其它线程都会阻塞等待,直到活动线程执行 () 方法完毕。如果在一个类的 () 方法中有耗时的操作,就可能造成多个线程阻塞,在实际过程中此种阻塞很隐蔽。

示例代码如下:

public class DeadLoopClassDemo {

    static class DeadLoopClass {
        static {
            /*如果不加上这个if语句,编译器将提示"Initializer does not complete normally"并拒绝编译*/
            if (true) {
                System.out.println(Thread.currentThread() + "init DeadLoopClass");
                while (true) {
                }
            }
        }
    }

    public static void main(String[] args) {
        Runnable script = () -> {
            System.out.println(Thread.currentThread() + "start");
            DeadLoopClass dlc = new DeadLoopClass();
            System.out.println(Thread.currentThread() + "run over");
        };
        Thread thread1 = new Thread(script);
        Thread thread2 = new Thread(script);
        thread1.start();
        thread2.start();
    }
}

三、类与类加载器

两个类相等,需要类本身相等,并且使用同一个类加载器进行加载。这是因为每一个类加载器都拥有一个独立的类名称空间。

这里的相等,包括类的 Class 对象的 equals() 方法、isAssignableFrom() 方法、isInstance() 方法的返回结果为 true,也包括使用 instanceof 关键字做对象所属关系判定结果为 true。

四、类加载器分类

从 Java 虚拟机的角度来讲,只存在以下两种不同的类加载器:

  • 启动类加载器(Bootstrap ClassLoader),使用 C++ 实现,是虚拟机自身的一部分;
  • 所有其它类的加载器,使用 Java 实现,独立于虚拟机,继承自抽象类 java.lang.ClassLoader。

从 Java 开发人员的角度看,类加载器可以划分得更细致一些,类似于原始部落结构,存在权力等级制度。

最高层:启动类加载器(Bootstrap ClassLoader)。

  • 使用 C++ 实现,是虚拟机自身的一部分;
  • 负责加载 <JAVA_HOME>/lib路径下的核心类库,无法被Java程序直接引用。
  • 是最根基的类加载器,负责装载最核心的 Java 类,比如 Object, System, String 等

第二层:扩展类加载器(Extension ClassLoader),JDK9 及以后的版本 称为平台类加载器(Platform ClassLoader)。

  • 负责加载 <JAVA_HOME>/lib/ext 路径下的扩展类库,开发者可以直接使用扩展类加载器
  • 用以加载一些扩展的系统类,比如 XML ,加密、压缩相关的功能类等

第三层:应用程序类加载器(Application ClassLoader)

  • 这个类加载器是 ClassLoader 中的 getSystemClassLoader() 方法的返回值,因此一般称为系统类加载器
  • 负责加载用户类路径(ClassPath)上所指定的类库
  • 如果应用程序中没有自定义过自己的类加载器,一般情况下这个就是程序中默认的类加载器

五、双亲委派模型

描述

低层次的当前类加载器,不能覆盖更高层次类加载器已经加载的类。如果低层次的类加载器想加载一个未知类,要非常礼貌地向上逐级询问 :“请问,这个类已经加载了吗?” 被询问的高层次类加载器会自问两个问题,第一,我是否已加载过此类?第二,如果没有,是否可以加载此类?只有当所有高层次类加载器在两个问题上的答案均为“否”时,才可以让当前类加载器加载这个未知类。如上图所示,左侧绿色箭头向上逐级询问是否已加载此类,直至 Bootstrap ClassLoader ,然后向下逐级尝试是否能够加载此类,如果都加载不了,则通知发起加载请求的当前类加载器 ,准予加载。

简单一句话: 一个类加载器首先将类加载请求转发到父类加载器,只有当父类加载器无法完成时才尝试自己加载。

该模型要求除了顶层的启动类加载器外,其它的类加载器都要有自己的父类加载器。这里的父子关系一般通过组合关系(Composition)来实现,而不是继承关系(Inheritance)。

优点好处

采用双亲委派模式的是好处是Java类随着它的类加载器一起具备了一种带有优先级的层次关系,通过这种层级关可以避免类的重复加载,当父亲已经加载了该类时,就没有必要子ClassLoader再加载一次。其次防止恶意覆盖Java核心API。

例如 java.lang.Object 存放在 rt.jar 中,如果编写另外一个 java.lang.Object 并放到 ClassPath 中,程序可以编译通过。由于双亲委派模型的存在,所以在 rt.jar 中的 Object 比在 ClassPath 中的 Object 优先级更高,这是因为 rt.jar 中的 Object 使用的是启动类加载器,而 ClassPath 中的 Object 使用的是应用程序类加载器。rt.jar 中的 Object 优先级更高,那么程序中所有的 Object 都是这个 Object。

双亲委派模型 代码实现

以下是抽象类 java.lang.ClassLoader 的代码片段,其中的 loadClass() 方法运行过程如下:先检查类是否已经加载过,如果没有则让父类加载器去加载。当父类加载器加载失败时抛出 ClassNotFoundException,此时尝试自己去加载。

public abstract class ClassLoader {
    // The parent class loader for delegation
    private final ClassLoader parent;

    public Class<?> loadClass(String name) throws ClassNotFoundException {
        return loadClass(name, false);
    }

    protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
        synchronized (getClassLoadingLock(name)) {
            // First, check if the class has already been loaded
            Class<?> c = findLoadedClass(name);
            if (c == null) {
                try {
                    if (parent != null) {
                        c = parent.loadClass(name, false);
                    } else {
                        c = findBootstrapClassOrNull(name);
                    }
                } catch (ClassNotFoundException e) {
                    // ClassNotFoundException thrown if class not found
                    // from the non-null parent class loader
                }

                if (c == null) {
                    // If still not found, then invoke findClass in order
                    // to find the class.
                    c = findClass(name);
                }
            }
            if (resolve) {
                resolveClass(c);
            }
            return c;
        }
    }

    protected Class<?> findClass(String name) throws ClassNotFoundException {
        throw new ClassNotFoundException(name);
    }
}

什么情况下需要自定义类加载器呢?

  1. 隔离加载类。 在某些框架内进行中间件与应用的模块隔离,把类加载到不同的环境。
  2. 修改类加载方式。 类的加载模型并非强制,除了Bootstrap以外,其他的加载并非一定要引入,或者根据实际情况在某个时间点进行按需进行动态加载。
  3. 扩展加载源。比如从数据库、网络,甚至电视机机顶盒进行加载。
  4. 防止源码泄露。Java 代码容易被编译和篡改,可以进行编译加密。那么类加载器也需要自定义,还原加密的字节码。

六、学以致用

1. 自定义类加载器

java.lang.ClassLoader 的 loadClass() 实现了双亲委派模型的逻辑,自定义类加载器一般不去重写它,但是需要重写 findClass() 方法。

如示例:

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 (Exception e) {
            e.printStackTrace();
        }
        throw new ClassNotFoundException(name);
    }

    private byte[] getClassFromCustomPath(String name) {
        // TODO 从自定义路径中加载指定类
        return null;
    }
}

2. 查看Boostrap ClassLoader 加载的类库


public static void main(String[] args) {
	URL[] urls = sun.misc.Launcher.getBootstrapClassPath().getURLs();
	for (URL url : urls) {
		System.out.println(url.toExternalForm());
	}
}

执行结果:

file:/C:/Program%20Files/Java/jdk1.8.0_131/jre/lib/resources.jar
file:/C:/Program%20Files/Java/jdk1.8.0_131/jre/lib/rt.jar
file:/C:/Program%20Files/Java/jdk1.8.0_131/jre/lib/sunrsasign.jar
file:/C:/Program%20Files/Java/jdk1.8.0_131/jre/lib/jsse.jar
file:/C:/Program%20Files/Java/jdk1.8.0_131/jre/lib/jce.jar
file:/C:/Program%20Files/Java/jdk1.8.0_131/jre/lib/charsets.jar
file:/C:/Program%20Files/Java/jdk1.8.0_131/jre/lib/jfr.jar
file:/C:/Program%20Files/Java/jdk1.8.0_131/jre/classes

3. 如何在启动时观察加载了哪个jar包中的哪个类?

使用-XX:+TraceClassLoading参数,可以在启动时观察加载了哪个jar包中的哪个类。此参数在解决类冲突时特别实用。因为不同JVM环境对于加载类的顺序并非是一致的。

部分示例:

[Opened C:\Program Files\Java\jdk1.8.0_131\jre\lib\rt.jar]
[Loaded java.lang.Object from C:\Program Files\Java\jdk1.8.0_131\jre\lib\rt.jar]
[Loaded java.io.Serializable from C:\Program Files\Java\jdk1.8.0_131\jre\lib\rt.jar]
[Loaded java.lang.Comparable from C:\Program Files\Java\jdk1.8.0_131\jre\lib\rt.jar]
[Loaded java.lang.CharSequence from C:\Program Files\Java\jdk1.8.0_131\jre\lib\rt.jar]
[Loaded java.lang.String from C:\Program Files\Java\jdk1.8.0_131\jre\lib\rt.jar]
[Loaded java.lang.reflect.AnnotatedElement from C:\Program Files\Java\jdk1.8.0_131\jre\lib\rt.jar]
[Loaded java.lang.reflect.GenericDeclaration from C:\Program Files\Java\jdk1.8.0_131\jre\lib\rt.jar]
[Loaded java.lang.reflect.Type from C:\Program Files\Java\jdk1.8.0_131\jre\lib\rt.jar]
[Loaded java.lang.Class from C:\Program Files\Java\jdk1.8.0_131\jre\lib\rt.jar]
[Loaded java.lang.Cloneable from C:\Program Files\Java\jdk1.8.0_131\jre\lib\rt.jar]
[Loaded java.lang.ClassLoader from C:\Program Files\Java\jdk1.8.0_131\jre\lib\rt.jar]
[Loaded java.lang.System from C:\Program Files\Java\jdk1.8.0_131\jre\lib\rt.jar]
[Loaded java.lang.Throwable from C:\Program Files\Java\jdk1.8.0_131\jre\lib\rt.jar]
......

4. 观察特定类的加载上下文

由于加载的类数量众多,调试时很难捕捉到指定类的加载过程,这时可以使用条件断点功能。拿HashMap的加载过程为例,在ClassLoader#loadClass()处打个条件断点,效果如下,


本文转载自:面试被怼?还搞不懂JVM?阿里架构师带你掌握JVM类加载机制

四面阿里巴巴面经总结:从零到P7架构师的成长之路 成为一名P7级架构师是众多技术人员的梦想,而在阿里巴巴四次面试后成功入职,则是一段充满挑战和成长的旅程。本文将分享一位经历四次阿里巴巴面试的技术人员的面试经验和成长之路。作者将详细回顾自己在阿里巴巴的四次面试过程,包括每一轮面试的重点和问题。通过分享这些面试经验,读者将能够了解到阿里巴巴面试的特点和技巧,并从中获得宝贵的参考和指导。此外,作者还将分享自己在成为P7级架构师的过程中所经历的成长和挑战。包括如何提升技术能力、如何在团队中展现领导才能、如何处理工作与生活的平衡等方面。 阅读详情

相关推荐

前阿里P7架构师,分享多年工作心得and面试经验,祝你圆大厂梦

我是2018年9月初开始接触工作机会和视频面试,9月10日也就是马云老师在教师节宣布即将卸任的那天,我接到了电话邀请我去杭州终面,当时我乐的屁颠屁颠的,觉得啊这都是缘分啊。面试很顺利,给了P7+,也有股票,后面的体检和背景调查都很顺利,为了体验双11,我国庆后回来就辞职,然后无缝衔接的搬家去了杭州,住进公司统一安排的维也纳酒店,火速入职加入了双11战役,看着西溪园区的灯火通明,觉得自己激情澎湃。 双11熬了几天夜,开始复盘,开始调整,开始每周六给老板写7K字+的部门周报。开始拥抱变化。面试...

文章中资料均可获取,有需要请添加yunduoa2019即可 694

java类加载机制,再也不怕面试官的刁难

上一篇我们详细的讲解了java 虚拟机的内存模型(要想精通java,你必须得知道java的内存模型,不忽悠),并且知道了我们写的代码分别是怎么存在JVM的哪个内存区域中。今天我们来看另一个重要的问题,类加载机制的核心知识,这个知识也是面试经常问到的。 我们的java代码是怎么运行起来的? 我们在写好java代码之后,都是先进行打包,打成jar包或者war包,最后丢到服务器上启动JVM进程就能运...

csdn681的博客 2235

具身智能的边缘计算核心构成方案

摘要: 具身智能(Embodied Intelligence)依赖物理实体与环境交互,而边缘计算(Edge Computing)通过本地化数据处理降低延迟、提升实时性。两者结合的核心方案包含五层架构:传感器层采集环境数据,边缘处理单元执行本地计算,通信模块实现低延迟传输,决策引擎运行轻量AI模型,执行器接口转化动作为物理操作。该方案以“边缘优先”为原则,满足毫秒级响应(如延迟<50ms),同时优化能效(功耗降低30%)和隐私保护。适用于机器人、自动驾驶等场景,通过分层闭环设计确保在资源受限环境中的可靠

老郑的博客 810

理解JVM并不难,看完阿里大佬整理的JVM文档,看完手撕面试官

理解JVM并不难,看完阿里大佬整理的JVM文档,看完手撕面试官 提到Java虚拟机(JVM),可能大部分人的第一印象是“难”,但当让我们真正走入“JVM世界”的时候,会发现其实问题并不像我们想象中的那么复杂。唯一真正令我们恐惧的,其实是恐惧本身。 JVM 的内存模型和 JVM 的垃圾回收机制一直是 Java 业内从业者绕不开的话题(实际调优、面试)JVM是java中很重要的...

Javazhoumou的博客 5805

使用 ONLYOFFICE API 构建 Java 转换器,在 Word 和 PDF 之间进行转换

随着文档处理需求的增加,格式转换成为了一个重要的需求点。由于PDF格式具有跨平台、不易被篡改的特性,将Word格式(.docx)转换为PDF格式(.pdf)的需求尤为强烈。ONLYOFFICE作为一个强大的办公套件,提供了这样的转换功能,使得用户可以轻松地在Word和PDF之间进行转换。

ONLYOFFICE的官方博客 4567

从频谱分析到硬件加速:用ZYNQ-7020+FFT IP核实现实时信号处理的完整方案

本文详细介绍了如何利用ZYNQ-7020和FFT IP核实现实时信号处理的完整方案,涵盖系统架构设计、硬件加速实现及性能优化。通过异构计算架构,该方案将1024点FFT处理延迟压缩至28μs,显著提升工业自动化和无线通信等领域的实时频谱分析效率。

weixin_33704234的博客 467

阿里面试必问之JVM

对于Java程序员来说,在众多Java知识点当中JVM是很重要的一块,在Java程序员面试的时候往往也会考察这方面的知识。比如新浪、阿里、腾讯、百度、美团、小米等大厂在面...

JAVA高级架构 301

STM32实战:如何用GPS信号同时同步海康摄像头和Livox Mid-360雷达(附完整接线图)

本文详细介绍了如何利用STM32实现GPS信号分频,同步海康摄像头和Livox Mid-360雷达的时间同步方案。通过硬件架构设计、STM32信号处理核心实现及设备接口规范,解决了多传感器数据融合中的时间对齐难题,适用于自动驾驶和机器人导航领域。

weixin_29182481的博客 596

阿里巴巴Java架构师岗面试题(正式版)!

1、为什么要用SpringBoot2、Spring Boot的核心注解是哪个?它主要由哪几个注...3、运行Spring Boot有哪几种方式?4、如何理解Spring Boot中的Starters?5、如何在Spring Boot启动的时候运行—些特定的代码?6、Spring Boot需要独立的容器运行吗?7、Spring Boot中的监视器是什么?8、如何使用Spring Boot实现异常处理?9、你如何理解Spring Boot中的Starters?

程序员高级码农的博客 1319

基于综合阻抗特征的配电架空线路单相断线故障区段定位研究

本文提出了一种基于综合阻抗特征的配电架空线路单相断线故障区段定位方法。通过分析故障后正序、负序阻抗变化,构造综合阻抗判据实现精准定位。仿真结果表明:该方法能有效识别故障区段,差异度判据显著(故障区段达0.508,非故障区段<0.016);对过渡电阻(1-200Ω)和负荷变化具有强鲁棒性,定位准确率不受影响。相比传统方法,综合阻抗法放大了断线故障特征,解决了弱故障信号检测难题,为配电网安全运行提供了可靠的技术手段。

AI的内部世界的博客 78

MATLAB计算各种复合干热指数,如SDHI、DHMI等

MATLAB编程实现各种复合干热指数

WW、forever的博客 5079

膜拜大佬!JVM性能调优——JVM内存模型和类加载运行机制

一、JVM内存模型 运行一个 Java 应用程序,必须要先安装 JDK 或者 JRE 包。因为 Java 应用在编译后会变成字节码,通过字节码运行在 JVM 中,而 JVM 是 JRE 的核心组成部分。JVM 不仅承担了 Java 字节码的分析和执行,同时也内置了自动内存分配管理机制。这个机制可以大大降低手动分配回收机制可能带来的内存泄露和内存溢出风险,使 Java 开发人员不需要关注每个对象的内存分配以及回收,从而更专注于业务本身。 在 Java 中,JVM 内存模型主要分为堆、方法区、程序计数...

小梦爱Java的博客 883

具身智能:原理、算法与系统 第18章 模仿学习与人类示范

与基于试错机制的强化学习不同,模仿学习假设存在能够提供高质量轨迹示范的专家策略,学习者的目标是在不直接访问专家内部决策机制的情况下,复现或泛化专家的行为模式。此外,选项 GAIL(Option-GAIL)将分层强化学习与对抗模仿结合,学习选项(Options)级别的策略,能够捕捉专家示范中的多模态行为与高层意图。X-Sim 框架提出从真实到模拟再到真实的迁移路径:首先从人类视频中重建物理仿真环境,在仿真中训练状态级策略,随后通过策略蒸馏获得基于视觉的策略,最后通过在线领域自适应对齐真实与仿真观测。

VectorShift的博客 125

针对金三银四整理了100道JVM虚拟机高频面试题,你全会的话面个阿里没什么问题!

前言 JVM ,即“Java 虚拟机”,有点类似于“操作系统”,上面跑着Java程序。 其实我们在平常的工作中,并不会直接接触到JVM,但是经常会遇到与之相关的问题: 一段代码有问题,执行效率低,但就是无法找到深层次原因。 线上系统CPU疯狂运转, GC时间飙升,产生卡顿,严重影响服务响应时间; 正在运行的Java程序,突然就OOM(内存溢出)了; 要做性能优化时面对一堆JVM的参数无从下手… 这些问题其实都和JVM有关系。 我还记得曾经有一次花了整整一周时间,才定位到一个棘手的堆外内存

欢迎您访问我的公众号【前程有光】 4265

【WorkBuddy专栏51】Codex与WorkBuddy的底层基因——两条完全不同的AI智能体路线(上)

【WorkBuddy专栏51】Codex与WorkBuddy的底层基因——两条完全不同的AI智能体路线(上)

AI人人懂 2162

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

面试阿里找个架构师想吊打我,架构师很厉害吗?阿里我进定了,架构师也拦不住我!

前言 人人都有大厂梦,对于程序员来说,BAT为首的一线互联网公司肯定是自己的心仪对象,毕竟能到这些大厂工作,不仅薪资高待遇好,而且能力技术都能够得到提升,最关键的是还能够给自己镀上一层金,让人瞻仰。 同样的,我自己的个人目标也是阿里,但之前一直在一家小公司,一呆就是好几年,现在通过不断学习和实践,提升了自己很多,也有了信心来阿里挑战。下面,就是我这次面试阿里P6的一些经历和心得。 阿里P6岗面试经历 这次阿里的面试经历实在太紧张+刺激+尴尬了,面试前还自信满满,面试后被吊打得怀疑人生。整个流

javassb的博客 437

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

在我逼问之下,大佬终于说出了自己面试阿里的诀窍,现在我就分享给大家!

前言 本来今天我是不打算更新的,刚好想起前几天有个粉丝给我发了个邮件,大概的意思就是自己进来阿里,想把自己的经历和面试题分享给大家,把素材都发给我了,让我帮忙整理一下发出来,话不多说,干货在下面了! 一面: 开始是自我介绍; HashMap的实现原理,什么是hash碰撞,怎样解决hash碰撞? ConcurrentHashMap的原理,与HashTable的区别? HashSet和TreeSet的区别以及底层实现原理 HashMap中存key-value,value有重复但是都是Comp

欢迎您访问我的公众号【前程有光】 4547

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

做了三年的程序员!从刚毕业的小白到现在的阿里架构师,我是这样学习java的!

个人近期面试情况 今年二月以来,我的面试除了一个用友的,基本其他都被毙了,可以说是非常残酷的。其中有很多自己觉得还面的不错的岗位,比如百度、跟谁学、好未来等公司。说实话,打击比较大。 情况基本上是从4月开始好起来的,这个时间点,可能疫情快过去了,国家也开启了接近40万亿的基础建设计划,在这个时间段,面试的几个代表性的公司,包括腾讯、饿了么、宝宝树、旷世科技等等,基本都成了。 最终,就在7月底,蚂蚁金服给我确认了p7的职位。也算自己到了另一个奋斗的阶段了。对自己的经历,做一个面试总结。 我的面试准备 面试其实

weixin_53170315的博客 7328

慌了!面试官又拿JVM开怼!

无论什么级别的Java从业者,JVM都是进阶时必须迈过的坎。不管是工作还是面试中,JVM都是必考题。如果不懂JVM的话,薪酬会非常吃亏(近70%的面试者挂在JVM上了)。之前一哥们就是工...

JAVA葵花宝典 340

复习这份美团架构师的Java核心面试宝典,我四面阿里拿下offer

怎样才能拿到大厂的offer,没有掌握绝对的技术,那么就要不断的学习

javaAnPou的博客 148

复习这份阿里架构师的Java核心面试宝典,我四面腾讯拿下offer

他是如何拿下腾讯等大厂的offer的呢,今天分享他的秘密武器,阿里资深架构师整理的Java核心知识点,面试时面试官必问的知识点,篇章包括了很多知识点,其中包括了有基础知识、Java集合、JVM、多线程并发、spring原理、微服务、Netty 与RPC 、Kafka、日记、设计模式、Java算法、数据库、Zookeeper、分布式缓存、数据结构等等。由于整个文档比较全面,内容比较多,所以我分享的知识里面可能会有一些疏漏,与杂乱,整个核心知识点都是整理好的文档。...

m0_62051288的博客 354

阿里架构大牛说:JVM从入门到入魔,就是这么简单!

JVM是绝大多数Java小白的一道坎,同时也是2到3年程序员面试的高频点,就像是古代大侠的内功心法,只有招数没有内功那绝对是不行的!通过学习JVM,不仅可以深入理解代码从编译到加载的过程、内存中对象的创建与垃圾回收、日常开发中快速定位性能问题等,也可以作为面试不可缺少的加分项。 但是阿里架构大牛说:JVM从入门到入魔,就是这么简单!那么咱们今天就来唠叨一番... 先上一份自己整理的xmind的JVM学习大纲(梳理一下知识点)... xmind的JVM学习大纲.png 这里是图片展示的xmind

mifffy_java的博客 448

Java面试题--JVM大厂篇之JVM 大厂面试题及答案解析(1)

本文涵盖了来自阿里巴巴、腾讯、百度、字节跳动等众多大厂的 JVM 面试题及详细解析。内容包括 JVM 内存模型、垃圾回收、引用类型、垃圾回收算法、GC Roots、类加载机制、JVM 调优、线程信息、对象晋升、内存泄漏、堆内存划分、逃逸分析、异常处理等多个重要方面。通过丰富的案例和清晰的解析,帮助读者深入理解 JVM 的关键概念和技术,为应对大厂面试和实际开发中的 JVM 相关问题提供有力支持。

【青云交】华为云云享专家 | 阿里云开发者社区专家博主 技术圈个人影响力前 9 | 博客之星 TOP12 优快云 首位四榜(原力榜 / 作者周榜 / 领军人物 / 综合热榜)榜首,破平台纪录! 苏州地区全榜霸榜,感恩全网十多万粉丝同行! 1959

阿里二面JVM相关面试题

JVM是面试中一直绕不过去的坎,如此我们就征服它,本文给大家整理了阿里二面出现的JVM相关的面试题,希望对你有所帮助 一、问题 1.JVM内存模型,GC机制和原理;2.GC分哪两种,Minor GC 和Full GC有什么区别?什么时候会触发Full GC?分别采用什么算法?3.JVM里的有几种classloader,为什么会有多种?4.什么是双亲委派机制?介绍一些运作过程,双亲委派模型的好处;5.什么情况下我们需要破坏双亲委派模型;6.常见的JVM调优方法有哪些?可以具体到调整哪个参数,调成什么值?7..

jvm__cgmx9880的博客 162

JVM加载class文件的原理机制详解

1、JVM简介   JVM是我们Javaer的最基本功底了,刚开始学Java的时候,一般都是从“Hello World”开始的,然后会写个复杂点class,然后再找一些开源框架,比如Spring,Hibernate等等,再然后就开发企业级的应用,比如网站、企业内部应用、实时交易系统等等,直到某一天突然发现做的系统咋就这么慢呢,而且时不时还来个内存溢出什么的,今天是交易系统报了StackOverflowError,明天是网站系统报了个OutOfMemoryError,这种错误又很难重现,只有...

小梦爱Java的博客 556
上一篇: 圆你的大厂梦!字节跳动Java高频面试题真题:一/二/三面+常见问题
下一篇: BAT直通车:阿里架构师详解JVM垃圾回收机制,看完还不懂那就放弃吧
Java_supermanNO1
博客等级 码龄7年 1170粉丝 329原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值