JVM结构化体系

目录

目录

1.JVM 简介

1.1. 如何理解 JVM 呢?

 1.2. 市场主流 JVM 分析?

1.3. 为什么要学习 JVM?

1.4. 字节码底层是如何执行呢?

如何理解 JIT 呢?

为什么 JVM 中解释执行与编译执行的并存(混合模式)?

1.5. 如何理解 JVM 的运行模式?

如何查看现在 JVM 的工作模式?

2.JVM 体系结构

2.1. JVM 的产品架构是怎样的?

2.2. JVM 运行时内存结构是怎样的?

2.2.1. JVM 线程共享区应用分析

1. Heap (堆内存):

2. Method Area (方法区)

2.2.2. JVM 线程私有区应用分析

1. Program Counter Register (程序计数器)

2. Stack Area (虚拟机栈区)

3. Native Stack Area (本地方法栈)

 3.JVM 应用参数分析

3.1. 如何理解 JVM 中的内存溢出?

代码演示:堆内存溢出

代码演示:元数据内存溢出(JDK8)

3.2. JVM 工具应用分析篇

3.2.1. 命令行工具篇

1. Jps [options] [hostid] (hostid 为 ip 或域名地址)

2. jmap -heap pid

3. jstack 用于生成 java 虚拟机当前时刻的线程快照


1.JVM 简介

1.1. 如何理解 JVM 呢?

JVM(Java Virtual Machine) 是:
1) JAVA 平台的一部分,是一种能够运行 Java bytecode 的虚拟机。
2) 是硬件计算机的抽象 ( 虚构 ) 实现,可以解释执行 JAVA 字节码。
3) 是实现 JAVA 跨平台运行的基石。

 1.2. 市场主流 JVM 分析?

JVM 是一种规范基于这种规范,不同公司就对此规范做了具体实现,例如市场上
的一些主流 JVM 如下:
1. JRockit VM (BEA 公司研发,后在 2008 年由 Oracle 公司收购 )
2. HotSpot VM (Sun 公司研发,后在 2010 年由 Oracle 公司收购 )
3. J9 VM IBM 内部使用)
说明: HotSpot 目前是应用最官方,最主要的一款 JVM 虚拟机

1.3. 为什么要学习 JVM

深入理解 JVM 可以帮助我们从平台角度提高解决问题的能力,例如:
1) 有效防止内存泄漏( Memory leak
2) 优化线程锁的使用 (Thread Lock) 齐雷 qilei@tedu.cn
1-4
3) 科学进行垃圾回收 (Garbage collection)
4) 提高系统吞吐量 (throughput)
5) 降低延迟 (Delay) ,提高其性能 (performance)

1.4. 字节码底层是如何执行呢?

JAVA 源程序编译,执行过程如下图所示:

在主流的 JVM (例如 HotSpot )中 , class 文件翻译成机器码执行时提供了两
种方式,如下图所示:1
其中:
1) 热点代码: 一般泛指循环或高频使用的方法。
2) 解释执行器:负责逐条将字节码翻译成机器码并执行。
3) 编译执行器:负责即时编译 (Just-In-Time compilation,JIT) 执行。

如何理解 JIT 呢?

JIT( 即时编译 ) 是用来提高 java 程序运行效率的一种技术 , 基于这种技术,可以
字节码编译成平台相关的原生机器码,并进行各个层次的优化,这些机器码会被
缓存起来,以备下次使用。

为什么 JVM 中解释执行与编译执行的并存(混合模式)?

解释器与编译器两者各有优势,当程序需要迅速启动和执行的时候,解释器可以
首先发挥作用,省去编译的时间,立即执行。在程序运行后,随着时间的推移,
即时编译( JIT )逐渐发挥作用,它可以对反复执行的热点代码以方法为单位进
行即时编译,可以获取更高的执行效率。但是如果 JIT 对每条字节码都进行编
译,缓存 ( 缓存的指令是有限的 ) ,会增加开销。所以当程序运行环境中内存资源
限制较大(如部分嵌入式系统中),可以使用解释器执行节约内存,反之可以使
用编译执行来提升效率。

1.5. 如何理解 JVM 的运行模式?

JVM 有两种运行模式 Server Client。两种模式的区别在于,Client

式启动速度较快, Server 模式启动较慢;但是启动进入稳定期之后 Server
式的程序运行速度比 Client 要快很多。这是因为 Server 模式启动的 JVM 采用
的是重量级的虚拟机,对程序采用了更多的优化;而 Client 模式启动的 JVM
用的是轻量级的虚拟机。所以 Server 启动慢,但稳定后速度比 Client 远远要
快。

如何查看现在 JVM 的工作模式?

说明:现在 64 位的 jdk 中默认都是 server 模式。当虚拟机运行在 -client
模式的时候 , 使用的是一个代号为 C1 的轻量级编译器 , -server 模式启动的
虚拟机采用相对重量级 , 代号为 C2 的编译器 .c1 c2 都是 JIT 编译器, C2 C1 编译器编译的相对彻底 , 服务起来之后 , 性能更高 .

2.JVM 体系结构

2.1. JVM 的产品架构是怎样的?

JVM Java Hotspot Architecture :主要分为三大部分:
1) 类加载系统 ( ClassLoader System ) :负责加载类到内存
2) 运行时数据区 ( Runtime Data Area ):负责存储数据信息
3) 执行引擎 ( Execution Engine : 负责调用对象执行业务

2.2. JVM 运行时内存结构是怎样的?

JVM 启动运行 Class 文件时会对 JVM 内存进行切分,我们可以将其分为线程共

享区和线程独享区。如下图所示 .
其运行时内存详细架构如下:
备注:
 
1.在 JDK8 中持久代 (Permanent Generation)部分数据移到了元数据 ( Metaspace ),在 JDK8 中已经没有持久代。元空间的本质和永久代类似,都   JVM 规范中方法区的实现,不过元空间与永久代之间最大的区别在于:元空 间并不在虚拟机中,而是使用本地内存。因此,默认情况下,元空间的大小仅受 本地内存限制,但可以通过以下参数来指定元空间的大小。

2.永久代

在自定义类加载器还不是很常见的时候,类大多是static的,很少被卸载或收集,因此被成为“永久的(Permanent)”。

同时,由于类class是JVM实现的一部分,并不是由应用创建的,所以又被认为是“非堆(Non-Heap)”内存。

在JDK8之前的HotSpot JVM,存放这些“永久的”区域叫做“永久代(permanent generation)”。

2.2.1. JVM 线程共享区应用分析

1. Heap (堆内存)
堆内存概要:
1) 虚拟机启动时创建,被所有线程共享 , 用于存放所有 java 对象实例 .
2) 可分为年轻代 (eden) 和老年代 (Tenured)
3) 是垃圾收集器(GC)管理的主要区域
4) 堆中没有内存分配时将会抛出 OutOfMemoryError
对象在内存中分配说明:
新创建的对象一般都分配在年轻代,当对象比较大时年轻代没有足够空间存储时还可直接分配到老年代。 有时候系统为了减少 GC 开销对于小对象且没有逃逸的对象还 可以直接在栈上分配。
堆内存大小配置参数说明:
1) -Xms 设置堆的最小空间大小。
2) -Xmx 设置堆的最大空间大小。
3) -XX:NewSize 设置新生代最小空间大小。
4) -XX:MaxNewSize 设置新生代最大空间大小。
5) -XX:NewRatio 新生代和老年代的比值,值为 4 则表示新生代 : 比老年代 1: 4
6) -XX:SurivorRatio 表示 Survivor eden 的比值,值为 8 表示两个 survivor:eden=2:8.
8) -Xss: 设置每个线程的堆栈大小。
2. Method Area (方法区)
方法区(1.8以后叫元数据区)概要:
1) 非堆内存,逻辑上的定义, 用于存储类的数据结构信息,常量、静态变量以及即时编译器编译后的代码等数据。
由于元 数据存储的信息不容易变动,因此它被安置在一块堆外内存。
2) 不同 jdk ,方法区的实现不同, JDK8(hotspot)  中的方法区对应的是 Metaspace,是一 块本地内存。
方法存储说明: 
方法区内存配置参数说明:
1) -XX:PermSize 设置永久代最小空间大小( JDK8 已弃用)。
2) -XX:MaxPermSize 设置永久代最大空间大小( JDK8 已弃用)。
3) -XX:MetaspaceSize 设置元数据区最小空间。 (JDK8)
4) -XX:MaxMetaspaceSize 设置元数据区最大空间。 (JDK8)

2.2.2. JVM 线程私有区应用分析

1. Program Counter Register (程序计数器)
1) 线程启动时创建,线程私有。
2) 用于记录当前正在执行的程序的字节码指令地址
3) Java 虚拟机规范唯一一个没有内存溢出的区域。
2. Stack Area (虚拟机栈区)
虚拟机栈概要:
1) 用于存储栈帧 (Stack Frame) 对象,保存方法的局部变量表操作数
行运行时常量池的引用一些额外的附加信息
2)每  一次方法调用都会创建一个新的栈帧,并压栈。当方法执行完毕之后,便会
将栈帧出栈。
3) 栈上对象的分配:对于小对象(一般几十个 bytes ),在没有逃逸的情况下,可以
直接分配在栈上(直接分配在栈上,可以自动回收,减轻 GC 压力);大对象
或者逃逸对象无法栈上分配
说明:方法在进行递归调用时容易出现栈内存溢出。
虚拟机栈参数说明:
1 -Xss128k : 设置每个线程的栈大小
JDK5.0 以后每个线程堆栈大小为 1M ,以前每个线程堆栈大小为 256K。可根据应用的线程所需内存大小进行调整。在相同物理内存下,减小这个值能生成更多 的线程。但是操作系统对一个进程内的线程数还是有限制的,不能无限生成,经 验值在 3000~5000 左右。
3. Native Stack Area (本地方法栈)

1) 为虚拟机使用到的 Native 方法提供服务。
2) 用于存储本地方法执行时的一些变量信息,操作数信息,结果信息。

 3.JVM 应用参数分析

3.1. 如何理解 JVM 中的内存溢出?

每个 Java 程序运行时都会使用一定量的内存 , JVM 内存不足以满足当前 java 程序运行时所需要的内存资源时就会出现内存溢出的现象。

代码演示:堆内存溢出

在如下代码中假如不断的向 list 集合中存储新的对象,list 集合底层也会不 断的进行扩容,当内存中没有足够连续内存 空间存储这些对象时就会出现堆内 存溢出。
 
public class TestOOM01 {
    public static void main(String[] args) {
        long t1=System.currentTimeMillis();
        try {
            List<byte[]> list=new ArrayList<>();
            for(int i=0;i<100;i++) {
                list.add(new byte[1024*1024]);
            }
        }finally {
            long t2=System.currentTimeMillis();
//System.out.println("oom:"+(t2-t1));
        }
    }
}
运行时可设置虚拟机参数
-Xmx50m -Xms10m -XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=e:/a.dump
说明:如上代码在运行了一段时间以后会出现堆内存溢出 (OutOfMemoryError), 可通过调整堆内存大小,延迟内存溢出的时间。

代码演示:元数据内存溢出(JDK8)

当在有限的元数据内存区不断的加载新的类时会导致元数据区空间不足从而出 现内存溢出现象,例如:
public class MetaSpaceTest {

    public static void main(String[] args) {
        int i = 0;
        try {
            for (i = 0; i < 100000; i++) {
                new CglibBean(new HashMap<>());
            }
        } catch (Exception e) {
            System.out.println(e.getMessage());
        } finally {
            System.out.println("total create count:" + i);
        }
    }

    public static class CglibBean {

        public CglibBean(Object object) {
            Enhancer enhancer = new Enhancer();
            enhancer.setUseCache(false);
            enhancer.setCallback((MethodInterceptor) (obj, method, args, proxy) -> obj);
            enhancer.setSuperclass(object.getClass());
            enhancer.create();
        }
    }
}

上述代码通过Cglib生成大量的HashMap代理,下面我们在运行这段代码的时候指定下列参数

-XX:MaxMetaspaceSize=100M -XX:+PrintGCDetails

当我们程序循环至3660次,也就是说我们大约在生成了约3660个代理类以后元数据区发生了内存溢出,下面将MaxMetaspaceSize改为50M执行,

 从上图可以看出当我们生成了1710个代理类以后元数据区发生了内存溢出,可见一个元数据区的大小决定了Java虚拟机可以装载的类的多少。

3.2. JVM 工具应用分析篇

3.2.1. 命令行工具篇

1. Jps [options] [hostid] (hostid ip 或域名地址)
jps 是用于查看有权访问的 hotspot 虚拟机的进程,当未指定 hostid 时,默认 查看本机 jvm 进程。
-q 不输出类名、 Jar 包 名和传入 main 方法的参数
-m 输出传入 main 方法的参数
-l 输出 main 类或 Jar 的全限名
-v 输出传入 JVM 的参数
 例如:
代码示例
执行:
1)Jps -l 输出应用程序主类完整 package 名称或 jar 完整名称 .
2)Jps -v 列出 jvm 参数
2. jmap -heap pid
用于打印指定 Java 进程的对象内存映射或堆内的细节。
代码案例
public class TestCommand {
    public static void main(String[] args) {
        while (true) {
            byte[] b1 = new byte[1024 * 1024];
        }
    }

}
例如获取如上代码的进程 id 之后,执行 jmap -heap 24966 可检测堆的配置 信息,还可以借助 jmap -histo:live 1963 快速定位内存泄露。
其中:
1) MaxHeapFreeRatio:  最大空闲堆内存比例
最大空闲对内存比例, GC 后如果发现空闲堆内存大于整个预估堆内存的 N%(百分比 ) JVM 则会收缩堆内存,但不能小于 -Xms 指定的最小堆的限制。
2) MinHeapFreeRatio: 最小空闲堆内存比例
GC 后如果发现空闲堆内存小于整个预估堆内存的 N%( 百分比 ), JVM 会增大 堆内存,但不能超过 -Xmx 指定的最大堆内存限制。
3) MaxHeapSize: -Xmx, 堆内存大小的上限
4) InitialHeapSize: -Xms, 堆内存大小的初始值
5) NewSize: 新生代预估堆内存占用的默认值
6) MaxNewSize: 新生代占整个堆内存的最大值
7) OldSize: 老年代的默认大小 ,
8) NewRatio:
老年代对比新生代的空间大小 , 比如 2 代表老年代空间是新生代的两倍大小 .
9) SurvivorRatio:
Eden/Survivor 的值 . 例如 8 表示 Survivor:Eden=1:8, 因为 survivor   2 , 所以 新生代  Eden 的占比为 8/10 
10)MetaspaceSize:
分配给类元数据空间的初始大小 (Oracle 逻辑存储上的初始高水位,the initial high-water-mark ). 此值为估计值 . MetaspaceSize 设置得过大,会延长垃圾回收时间 . 垃圾回收过后 , 引起下一次垃圾回收的类元数据空间的 大小可能会变大
11)MaxMetaspaceSize:
是分配给类元数据空间的最大值 , 超过此值就会触发 Full GC. 此值仅受限系统内存的大小 , JVM 会动态地改变此值
12)CompressedClassSpaceSize:
类指针压缩空间大小 , 默认为 1G.
13)G1HeapRegionSize:
G1 区块的大小 , 取值为 1M 32M. 其取值是要根据最小 Heap 大小划分出 2048 个区块 .
说明 :jmap 在系统调优时通常会结合 jhat 来分析 jmap 生成的 dump 文件。
3. jstack 用于生成 java 虚拟机当前时刻的线程快照
生成线程快照的主要目的是定位线程出现长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致的长时间等待等。
示例代码:
class SyncTask02 implements Runnable {
    private List<Integer> from;
    private List<Integer> to;
    private Integer target;

    public SyncTask02(List<Integer> from, List<Integer> to, Integer target) {
        this.from = from;
        this.to = to;
        this.target = target;
    }

    @Override
    public void run() {
        moveListItem(from, to, target);
        
    }

    private static void moveListItem(List<Integer> from,
                                     List<Integer> to, Integer item) {
        log("attempting lock for list", from);
        synchronized (from) {
            log("lock acquired for list", from);
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            log("attempting lock for list ", to);
            synchronized (to) {
                log("lock acquired for list", to);
                if (from.remove(item)) {
                    to.add(item);
                }
                log("moved item to list ", to);
            }
        }
    }

    private static void log(String msg, Object target) {
        System.out.println(Thread.currentThread().getName() +
                ": " + msg + " " +
                System.identityHashCode(target));
    }
}

public class TestDeadLock02 {
    public static void main(String[] args) {
        List<Integer> list1 = new ArrayList<>(Arrays.asList(2, 4, 6, 8,
                10));
        List<Integer> list2 = new ArrayList<>(Arrays.asList(1, 3, 7, 9,
                11));

        Thread thread1 = new Thread(new SyncTask02(list1, list2, 2));
        Thread thread2 = new Thread(new SyncTask02(list2, list1, 9));
        thread1.start();
        thread2.start();
    }
} 
例如 执行 jstack -l 22345 ,检测到死锁问题:
3.2.2. GUI 工具篇:

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

新手教程 | 2024年最新Vmware17安装教程及许可证(详细图文)

目录 前言&#xff1a; 一、VMware Workstation 17 Pro 简介 二、下载安装&#xff08;以Windows为例&#xff09; 三、许可证 四、检查是否安装成功 前言&#xff1a; 重新装电脑后&#xff0c;安装虚拟机 一、VMware Workstation 17 Pro 简介 VMware Workstation 17 …

【JavaWeb】Day46.Mybatis——入门

JDBC介绍 通过Mybatis可以很方便的进行数据库的访问操作。其实java语言操作数据库&#xff0c;只能通过一种方式&#xff1a;使用sun公司提供的 JDBC 规范。Mybatis框架&#xff0c;就是对原始的JDBC程序的封装。 JDBC&#xff1a; ( Java DataBase Connectivity )&#xff0c…

元类的执行

class MetaB(type):def __new__(cls, name, bases, attrs):print(f"使用元类 {cls.__name__} 创建{name}类 ")return super().__new__(cls, name, bases, attrs)class A(metaclassMetaB):passclass C(A):pass元类MetaB的__new__方法应该只会在创建类A时被调用一次, 因…

YoloV9实战:从Labelme到训练、验证、测试、模块解析

模型实战 训练COCO数据集 本次使用2017版本的COCO数据集作为例子&#xff0c;演示如何使用YoloV8训练和预测。 下载数据集 Images: 2017 Train images [118K/18GB] &#xff1a;http://images.cocodataset.org/zips/train2017.zip2017 Val images [5K/1GB]&#xff1a;htt…

Python-VBA函数之旅-compile函数

目录 1、 compile函数&#xff1a; 1-1、Python&#xff1a; 1-2、VBA&#xff1a; 2、相关文章&#xff1a; 个人主页&#xff1a;https://blog.csdn.net/ygb_1024?spm1010.2135.3001.5421 compile函数在Python中有多个实际应用场景&#xff0c;它主要用于将字符串形式的…

【C++】类和对象③(类的默认成员函数:拷贝构造函数 | 赋值运算符重载)

&#x1f525;个人主页&#xff1a;Forcible Bug Maker &#x1f525;专栏&#xff1a;C 目录 前言 拷贝构造函数 概念 拷贝构造函数的特性及用法 赋值运算符重载 运算符重载 赋值运算符重载 结语 前言 本篇主要内容&#xff1a;类的6个默认成员函数中的拷贝构造函数…

matlab使用教程(45)—二维曲线图绘制进阶

1.绘制双y轴曲线图 此示例说明如何使用两个不同的 y 轴合并线图和条形图。此外&#xff0c;还演示如何自定义线条和条形。 使用 yyaxis 创建包含两个 y 轴的图表。图形函数以图表的活动侧为目标。使用 yyaxis 控制活动侧。使 用左侧的 y 轴绘制条形图。使用右侧的 y 轴绘制线…

PLC扩展更自由,钡铼IOy系列模块实现DI/DO/AI/AO任意组合

随着工业自动化的不断发展&#xff0c;PLC&#xff08;可编程逻辑控制器&#xff09;作为工业控制领域的核心设备&#xff0c;扮演着至关重要的角色。而钡铼IOy系列模块作为PLC的重要扩展设备&#xff0c;不仅实现了DI&#xff08;数字输入&#xff09;、DO&#xff08;数字输出…

KNIME 国际化支持投票

你的投票也许能让 KNIME 中文化快一点点。 i18n 是个很搞笑的单词&#xff0c;它是英文 internationalization 国际化的缩写。18 指的是首字母i和末字母n中间有18个字母。另外还有什么 K8s 也是一样&#xff0c;中间省去了8个字母 ... 真是懒的可以。指北君还想起一个类似的笑话…

算法设计与分析实验报告c++实现(矩阵链相乘、投资问题、完全背包问题、数字三角形、最小生成树、背包问题)

一、实验目的 1&#xff0e;加深学生对分治法算法设计方法的基本思想、基本步骤、基本方法的理解与掌握&#xff1b; 2&#xff0e;提高学生利用课堂所学知识解决实际问题的能力&#xff1b; 3&#xff0e;提高学生综合应用所学知识解决实际问题的能力。 二、实验任务 用动态…

懒人建站工具过时了?试试这6个WordPress主题,1小时实现高效建站

懒人建站工具&#xff0c;凭借简单易用、快速上手和个性化定制的特点&#xff0c;为不熟悉代码和程序的人提供了搭建美观实用网站的便捷途径。无需专业的前端开发知识&#xff0c;无需雇佣专业开发人员&#xff0c;用户便能轻松实现网站搭建&#xff0c;满足个人或企业需求。懒…

novel-plus文件部分

环境配置。windows下需要将application-dev.yml添加盘符&#xff0c;固定路径 在FileController中&#xff0c;存在任意文件上传&#xff0c;也就是在 存在问题&#xff0c;确实是任意文件上传&#xff0c;任意文件都可以上传&#xff0c;但是上传jsp等文件时&#xff0c;会…

windows编译xlnt,获取Excel表里的数据

用git拉取项目 这个文件是空的 要用git拉下来&#xff0c;使用终端编译xlnt库 点击解决方案 运行生成 然后新建项目&#xff0c;配置好库&#xff0c; #include <iostream> #include <xlnt/xlnt.hpp>int main() {// 打开 Excel 文件xlnt::workbook workbook;workb…

微信小程序scroll-view组件

一、介绍 当一个容器内容很多时&#xff0c;若容器无法显示完整内容&#xff0c;则可通过滚动操作查看所有内容 在微信小程序中scroll-view组件可以实现滚动效果 二、scroll-view组件的属性值 &#xff08;1&#xff09;scroll-x 【boolean型】 允许横向滚动条&#xff0c;默…

【C++】开始使用stack 与 queue

送给大家一句话&#xff1a; 忍受现实给予我们的苦难和幸福&#xff0c;无聊和平庸。 – 余华 《活着》 开始使用queue 与 stack 1 前言2 stack与queue2.1 stack 栈2.2 queue 队列2.3 使用手册 3 开始使用Leetcode 155.最小栈牛客 JZ31 栈的弹出压入序列Leetcode 150.逆波兰表达…

共享桌面,3分钟自己实现一个吧,还能听见麦克风声音哦

前言 关于【SSD系列】&#xff1a; 前端一些有意思的内容&#xff0c;旨在3-10分钟里&#xff0c; 500-1000字&#xff0c;有所获&#xff0c;又不为所累。 共享桌面程序&#xff0c;哇&#xff0c;高大尚耶&#xff01;其实不然&#xff0c;让我带你3分钟实现桌面共享程序&am…

【Entity Framework】你知道如何处理无键实体吗

【Entity Framework】你知道如何处理无键实体吗 文章目录 【Entity Framework】你知道如何处理无键实体吗一、概述二、定义无键实体类型数据注释 三、无键实体类型特征四、无键实体使用场景五、无键实体使用场景六、无键使用示例6.1 定义一个简单的Blog和Post模型&#xff1a;6…

sqlilabs靶场1—20题学习笔记(思路+解析+方法)

前几个题目较为简单&#xff0c;均尝试使用各种方法进行SQL注入 第一题 联合查询 1&#xff09;思路&#xff1a; 有回显值 1.判断有无注入点 2.猜解列名数量 3.判断回显点 4.利用注入点进行信息收集 爆用户权限&#xff0c;爆库&#xff0c;爆版本号 爆表&#xff0c;爆列&…

AI 领域精选高质量信息源分享

我在这篇 ChatGPT 发布一周年的总结文章中大模型时代&#xff0c;程序员如何实现自我成长&#xff1f;——一名普通开发者的 ChatGPT 一周年记&#xff0c;已经推荐了不少优质的信息源&#xff0c;但主要还是偏技术向&#xff0c;随着我自己的身份从纯研发角色转变为产品&#…

【Linux】服务器硬件及RAID配置实战

目录 一、服务器 1.服务器 2.查看服务器信息 二、RAID 磁盘阵列 三、软RAID的创建和使用 1.添加硬盘&#xff0c;fdisk分区&#xff0c;分区类型ID设置为 fd 2.使用mdadm创建软raid 3.格式化 4.挂载使用 5.mdadm 一、服务器 1.服务器 分类机架式居多 塔…