-
Java—内存模型独占部分:程序计数器、虚拟机栈、本地方法栈
2019-04-15 14:56:46线程私有:程序计数器、虚拟机栈、本地方法栈 线程共享:MetaSpace、Java堆 程序计数器 当前线程所执行的字节码行号指示器(逻辑) 改变计数器的值来选取下一条需要执行的字节码指令(if、for这些都需要程序...内存简介
JVM内存模型—JDK8
线程私有:程序计数器、虚拟机栈、本地方法栈
线程共享:MetaSpace、Java堆
程序计数器
当前线程所执行的字节码行号指示器(逻辑)
改变计数器的值来选取下一条需要执行的字节码指令(if、for这些都需要程序计数器)
和线程是一对一的关系即 "线程私有"
堆方法计数,如果是Native方法则计数器值为Undefined
不会发生内存泄漏
Java虚拟机栈(Stack)
Java方法执行的内存模型
包括多个栈帧
局部变量表:包含方法执行过程中的所有变量(boolean、char这些变量类型)
操作数栈:入栈、出栈、复制、交换、产生消费变量
代码的演示查看字节码
package com.binglian.jvm.model; import javax.management.relation.RoleUnresolved; public class ByteCodeSample { public static int add(int a,int b){ int c=0; c=a+b; return c; } }
javac
javap -verbose ByteCodeSample.class
字节码代码
>javap -verbose ByteCodeSample.class Classfile /C:/binglian/work/Java EE/binglian-javabasic/src/main/java/com/binglia n/jvm/model/ByteCodeSample.class Last modified 2019-4-15; size 293 bytes MD5 checksum 970f738721757e3908f5b2ff1bf3b248 Compiled from "ByteCodeSample.java" public class com.binglian.jvm.model.ByteCodeSample minor version: 0 major version: 52 flags: ACC_PUBLIC, ACC_SUPER Constant pool: //线程池的东西 #1 = Methodref #3.#12 // java/lang/Object."<init>":()V #2 = Class #13 // com/binglian/jvm/model/ByteCodeSamp le #3 = Class #14 // java/lang/Object #4 = Utf8 <init> #5 = Utf8 ()V #6 = Utf8 Code #7 = Utf8 LineNumberTable #8 = Utf8 add #9 = Utf8 (II)I #10 = Utf8 SourceFile #11 = Utf8 ByteCodeSample.java #12 = NameAndType #4:#5 // "<init>":()V #13 = Utf8 com/binglian/jvm/model/ByteCodeSample #14 = Utf8 java/lang/Object { public com.binglian.jvm.model.ByteCodeSample(); descriptor: ()V flags: ACC_PUBLIC Code: stack=1, locals=1, args_size=1 0: aload_0 1: invokespecial #1 // Method java/lang/Object."<init> ":()V 4: return LineNumberTable: line 5: 0 public static int add(int, int); descriptor: (II)I flags: ACC_PUBLIC, ACC_STATIC Code: stack=2, locals=3, args_size=2 0: iconst_0 1: istore_2 2: iload_0 3: iload_1 4: iadd 5: istore_2 6: iload_2 7: ireturn LineNumberTable: line 8: 0 line 9: 2 line 10: 6 } SourceFile: "ByteCodeSample.java"
执行add(1,2)相加的详细细节
局部变量表和操作数栈的交换过程
递归为什么会引发java.lang.StackOverflowError异常
解决方法:限制递归深度,使用for这些进行替换
本地方法栈
与虚拟机张相似,主要作用于标注native的方法
-
Java底层学习:内存模型、调优参数、堆和栈的区别、元空间与堆与线程独占部分间的联系、intern()方法在不同...
2019-09-09 18:47:23线程私有: 程序计数器:字节码指令 虚拟机栈:Java方法 本地方法栈:native方法 线程共享: MetaSpace:名称为元空间,类加载信息 常量池:字面量和符号引用量 堆:数组和类对象 1.1 程序计数器Program ...Java底层知识JVM二
一、Java的内存模型-JDK8
- 线程私有:
- 程序计数器:字节码指令
- 虚拟机栈:Java方法
- 本地方法栈:native方法
- 线程共享:
- MetaSpace:名称为元空间,类加载信息
- 常量池:字面量和符号引用量
- 堆:数组和类对象
1.1 程序计数器Program Counter Register
-
是当前线程锁执行的字节码行号指示器,逻辑地址
-
改变计算器的值来选取下一条需要执行的字节码指令,包括分支、循环等
-
和线程是一对一的关系,由于JVM的多线程是通过线程轮流切换并通过分配处理器执行时间来实现的,在任何一个确定的时间,处理器只会处理一个线程的一条指令,所以每个线程都有独立的程序计数器记录执行到哪一条指令
-
对Java方法计数,计数器则记录的是正在执行的虚拟机的字节码的指令地址,如果是Native方法则为null
1.2 Java虚拟机栈Stack
-
Java方法执行的内存模型
-
包含多个栈帧,因为每个方法被执行的时候都会创建一个栈帧,这是方法运行期间依赖的数据结构,栈帧里面包含局部变量表、操作栈、动态链接、返回地址等,补充:局部变量表包含方法执行过程中的所有变量,操作数栈用于入栈、出栈、复制、交换、产生消费变量
补充:局部变量表、操作栈与计数器讲解:
//创建文件 public class ByteCodeSample { public static int add(int a,int b){ int c = 0; c = a + b; return c; } } //终端反编译 F:\sc\src\main\java>javac com\derrick\jvm\model\ByteCodeSample.java //口语化形式来描述字节码文件 javap -verbose javac com\derrick\jvm\model\ByteCodeSample.class //获取add方法的描述 public static int add(int, int); descriptor: (II)I //括号两个II表示接收两个int变量,括号外I表示返回值为int flags: ACC_PUBLIC, ACC_STATIC //方法是public的,也是static的 Code: stack=2, locals=3, args_size=2 //操作数栈深度为2,本地变量容量为3,变量参数容量为2 0: iconst_0 1: istore_2 2: iload_0 3: iload_1 4: iadd 5: istore_2 6: iload_2 7: ireturn LineNumberTable: line 5: 0 //代码第五行对应字节码的第0行 line 6: 2 line 7: 6
补充:递归产生java.lang.StackOverflowError异常
当递归层数较小的时候可以计算出结果,但是递归层数大了之后结果为Exception in thread “main” java.lang.StackOverflowError,这是因为线程每执行一个方法时都会创建一个栈帧,并将栈帧压入到虚拟机栈中,当方法执行完毕后才将栈帧出栈,由于递归不断调用自己,递归过深,栈帧数超出虚拟栈深度
public class Fibonacci { public static int fibonacci(int n){ if(n ==0) return 0; if(n==1) return 1; return fibonacci(n-1)+fibonacci(n-2); } public static void main(String[] args){ System.out.println(fibonacci(100000)); } }
1.3 元空间MetaSpace与永久代PermGen区别
两者都是用来存在Class的信息,如method,field等,是方法区的实现,但是元空间使用本地内存,而永久代使用的是jvm的内存,则字符串常量池在永久代中,容易出现性能问题和内存溢出;类和方法的信息大小难以确定,给永久代的大小指定步确定;永久代会给GC带来不必要的复杂性
1.4 Java堆,即Java Heap
Java Heap是被所有线程共享的区,在虚拟机启动时创建,唯一目的便是存放对象实例,几乎所有对象实例都在这里分配内存,通过-Xmx控制其大小
二、JVM
2.1 调优参数
当调用java程序去执行指令的时候,可以调用以下3个参数去分别调整Java的堆、线程所占大小
-Xss:规定了每个线程虚拟机栈(堆栈)的大小,一般情况下256K,会影响并发线程数的大小- -Xms:初始的Java堆的大小,即该进程创建出来的时候专属Java堆的大小 -Xmx:当对象容量超过Java堆初始容量,堆扩容到最大值 java -Xms128m -Xmx128m -Xss256k -jar xxx.jar
2.2 堆和栈区别
内存分配策略:静态存储(编译时确定每个数据目标在运行时的存储空间要求,因而在编译时就便可以分配固定的内存空间,则要求程序不含可变数据结构、递归等存在 );栈式存储(数据区需求在编译时未知,运行时模块入口前确定, 运行时当进入一个程序模块的时候,必须知道该程序模块数据区的大小,才能分配内存);堆式存储(专门负责在编译时或运行时模块入口都无法确定存储要求的数据分配)
联系: 引用对象、数组时,栈里定义变量保存堆中目标的首地址
管理方式: 栈自动释放,JVM可以自己针对栈进行操作,该内存空间的释放是编译器就可以操作的内容;而堆是由垃圾回收器进行自动回收
空间大小: 栈比堆小,堆空间在一个java程序中需要存储较多的对象数据
碎片相关: 栈产生的碎片远小于堆,这是因为堆操作量比较大
分配方式: 栈支持静态和动态分配,静态分配是本身由编译器分配好的,而动态分配是根据情况,堆仅支持动态分配
效率: 栈的效率比堆高
2.3 元空间、堆、线程独占部分间的联系——内存角度
public class HelloJessi { private String name; //field public void sayHello(){ //method System.out.println("Hello"+name); } public void SetName(String name){ //method this.name=name; } public static void main(String[] args){ int a=1; HelloJessi hj = new HelloJessi(); //hj是存在于虚拟站的引用变量,指向我们真正创建好的实例 hj.SetName("Derrick"); hj.sayHello(); } }
2.4 不同JDK版本之间的intern()方法的区别——JDK6 VS JDK6+
String s = new String("Derrick"); s.intern();
JDK6:当调用intern方法时,如果当前字符串常量池先前已创建出该字符串对象,则返回池中的该字符串的引用,否则将此字符串对象添加到字符串常量池中,并且返回该字符串对象的引用。
JDK6+:当调用intern方法是,如果当前字符串常量池先前已创建出该字符串对象,则返回池中的该字符串的引用,否则,如果该字符串已经存在java堆中,则将堆中对此对象的引用添加到字符串常量池中,并且返回引用,如果堆中不存在,则在池中创建该字符串并返回其引用,避免常量池爆炸
public class InternDifference { public static void main(String[] args){ String s1 = new String("a"); s1.intern(); String s2 = "a"; System.out.println(s1==s2); String s3 = new String("a")+new String("a"); s3.intern(); String s4 = "aa"; System.out.println(s3==s4); } } //JDK6 运行结果:false false //JDK6+运行结果:false true
JDK6:interm是副本
JDK6+: interm是引用
- 线程私有:
-
jvm
2020-07-19 20:36:01又称方法栈,线程私有的,线程执行方法是都会创建一个栈阵,用来存储局部变量表,操作栈,动态链接,方法出口等信息.调用方法时执行入栈,方法返回式执行出栈. 3、本地方法栈 与栈类似,也是用来保存执行方法的信息.执行Java...1、JVM内存模型:
线程独占:栈,本地方法栈,程序计数器
线程共享:堆,方法区2、栈:
又称方法栈,线程私有的,线程执行方法是都会创建一个栈阵,用来存储局部变量表,操作栈,动态链接,方法出口等信息.调用方法时执行入栈,方法返回式执行出栈.
3、本地方法栈
与栈类似,也是用来保存执行方法的信息.执行Java方法是使用栈,执行Native方法时使用本地方法栈.
4、程序计数器
保存着当前线程执行的字节码位置,每个线程工作时都有独立的计数器,只为执行Java方法服务,执行Native方法时,程序计数器为空.
5、堆
JVM内存管理最大的一块,对被线程共享,目的是存放对象的实例,几乎所欲的对象实例都会放在这里,当堆没有可用空间时,会抛出OOM异常.根据对象的存活周期不同,JVM把对象进行分代管理,由垃圾回收器进行垃圾的回收管理
6、方法区:
又称非堆区,用于存储已被虚拟机加载的类信息,常量,静态变量,即时编译器优化后的代码等数据.1.7的永久代和1.8的元空间都是方法区的一种实现
-
深入浅出JVM
2019-10-03 21:25:41是线程私有的,线程在执行每个方法时候都会创建一个栈帧,用来存储局部变量表和动态链接,方法出口等信息,调用方法时执行入栈,方法返回时执行出栈。 本地方法栈 与栈类似,也是用来保存线程执行方法时的一些信息,...JVM内存模型
栈、本地方法栈、程序计数器都是线程独占,堆、方法区都是线程共享的。面试时主要回答两个点:- 各部分的功能
- 哪些是线程共享的,哪些是线程独占的
栈
是线程私有的,线程在执行每个方法时候都会创建一个栈帧,用来存储局部变量表和动态链接,方法出口等信息,调用方法时执行入栈,方法返回时执行出栈。
本地方法栈
与栈类似,也是用来保存线程执行方法时的一些信息,不同的是执行java方法时使用栈,执行native方法(一个Native Method是这样一个java的方法:该方法的实现由非java语言实现,比如C)时使用本地栈。
程序计数器
保存着当前线程执行的字节码位置,每个线程工作时都有一个独立的计数器。程序计数器只为执行java方法服务,执行native方法时程序计数器为空。
堆
是JVM管理中最大的一块,堆被所有线程共享,目的是为了存放对象的实例,几乎所有对象的实例都会存放在这里。当堆内存没有可用的空间时,会抛出OOM异常。
根据堆对象存活的周期不同,JVM把堆内存进行分代管理,由垃圾回收器来进行垃圾的回收管理。方法区
也是JVM中各个线程共享的区域,又叫C堆区,用于存储已被虚拟机加载的类信息、常量、静态变量、JVM优化后的代码等等。JDK1.7前的永久代和1.8后的MeteSpace都是方法区的一种实现。
JMM内存模型
是java的内存模型,和JVM内存模型是不一样的,JMM的目标定义程序中变量的访问规则。如上图所示,所有的共享变量都存储在主内存中共享,每个每个线程有自己的工作内存,工作内存中保存的是主内存变量的副本,线程中所有对变量的操作必须在自己的工作内存中执行,而不能直接读写主内存中的变量。
在多线程进行数据交互时,例如线程A、B,先由线程A读取这个变量,线程A修改完了变量是修改在自己的工作内存区中,线程B是不可见的,只有从A的工作内存区写回到主内存,线程B从主内存读取到后才能进行进一步的操作。由于指令重排序的存在,这个写和读的顺序有可能会被打乱,因此JMM需要提供原子性、可见性、有序性的保证类的加载与卸载
类的加载
双亲委派的好处:- 避免类的重复加载
- 避免java的核心api被篡改
分代回收
堆内存被分代管理,为什么?
主要是为了方便垃圾回收,这样做是基于两个事实:第一是大部分对象很快就不会使用,第二是还有一部分不会立即不使用但也不会持续很长时间。
虚拟机中划分为年轻代、老年代、永久代。看上图,- 年轻代主要是用来存放新创建的对象,分为Eden区和两个Surivor(幸存)区,大部分对象是在Eden区,当Eden区满时还存活的对象会在两个Survivor区交替保存,达到一定次数后,对象会晋升到老年代。
- 老年代主要保存年轻代晋升来的对象信息。
- 永久代主要来保存类信息
根据引用计数法、复制法、标记清楚法几种:
- 引用计数法:通过对象被引用的次数来确定对象是否还在被使用,缺点是无法解决循环引用的问题。
- 复制算法:需要from、to两块大小相同的内存空间,对象分配时只在from块进行,回收时把存活对象复制到to块中,并清空from块,然后交换两块的分工,把from块做为to块,把to块作为from块。缺点是内存使用率较低。
- 标记清除算法:分为标记和清楚不再使用的对象两个阶段,缺点是会产生内存碎片。例如CMS、G1、ZGC
CMS算法
是JDK1.7以前最主流的算法。
第一个阶段是初始标记,标记的结果集只是从root直接可达的对象,会出现stop the world。
第二个阶段是并发标记,GC线程和应用线程并发执行,主要是标记可达的对象。
第三个阶段是重新标记,这个阶段是第二个stop the world阶段,停顿时间比并发标记要小很多,但比初始标记稍长,主要对对象进行重新扫描并标记。
第四个阶段,是并发清理阶段,主要对垃圾的清理。
最后一个阶段是并发重置阶段,为下一次GC准备相关数据结构G1算法
在JDK1.9后成为了JVM的默认垃圾回收算法,G1的特点是保持高回收率的同时,减少停顿。G1算法取消了年轻代和老年代的物理划分,但它任然属于分代回收,G1算法将堆分为若干个区域reigen,如上图小方格所示,一部分区域用作年轻代,一部分用作老年代,还有另外一种专门用于存储巨型对象的分区,G1和CMS一样都遍历全部对象,然后标记对象引用情况,在清楚对象后,会对区域进行整合异动,整合碎片空间。
上图右边是G1的回收过程:ZGC算法
可以支持tb级别的堆,它非常高效,能够做到10ms以下的回收停顿时间,这么短的停顿时间,ZGC是如何做到的呢?我们来了解下ZGC的黑科技:- 着色指针:一个指针最大是64位,ZGC限制了指针只能占42位,这样寻址只会使用到42位 ,那么剩余的22位就可以用来保存额外的信息,ZGC就是利用指针的额外信息位在指针上对对象进行着色标记。
- 读屏障:来解决GC贤程和应用线程可能会并发修改对象状态的问题,而不是简单粗暴的使用STW来做全局的锁定,锁定只会在单个对象上产生,这样垃圾回收的大部分时候都不需要STW,因此ZGC的大部分时间都是并发处理
- 基于Region:不像G1是固定大小,而是动态决定大小,Region可以动态创建和销毁。这样可以更好的对大对象进行分配和管理。
- 压缩整理:CMS算法清理垃圾时是原地回收,会存在碎片问题。ZGC和G1一样也会在回收后对Region对象进行合并。
上图就是ZGC的回收过程面试考察点
1深入理解JVM内存模型
2了解类加载机制
3了解内存可见性
4了解常用的GC算法实现和适用场景
5能够根据业务场景选择合适JVM参数和GC算法
加分项
1编译器优化
编译器优化方面有深入了解的话,会让面试官觉着你对技术深度角有追求。例如如何利用栈上分配减少内存压力,如何编写适合内联代码的问题等等
2问题排查经验和思路
面试官都喜欢动手能力强的同学,例如解决过线上经常fullGC的问题,排查过内存泄露的问题
3JVM调优经验与思路
针对特定场景的优化经验或思路,例如针对高平发低延迟的场景如何调整jvm参数尽量降低停顿时间,针对队列处理如何尽可能提高吞吐率等等
4了解最新的技术趋势(例如ZGC、Graalvm)
真题汇总
1.简单描述下JVM的内存模型
2.什么情况下会触发FullGC
年轻代晋升时,老年底内存不足时
3.Java类加载器有几种,关系是什么?
4双亲委派机制的加载流程是怎样的?有什么好处?
51.8为什么使用Metespace替换掉PermGen?Metespace保存在哪里?
6 编译期会对指令做哪些优化?(简单描述编译器的指令重排)
7简单描述下volatie可以解决什么问题?如何做到的?
强制主内存读写同步及防止指令重排序两点
8 简单描述下GC的分代回收
9 G1回收算法与CMS算法的区别在哪里?
10 对象引用有哪几种方式,有什么特定?
强弱软虚四种引用,以及在Jav中的处理方式
11使用过哪些JVM调试工具,主要分析哪些内容?
java自带的这些工具,例如堆分析工具Mat,线程分析工具jstack,获取堆信息的JMap等等
-
Java虚拟机面试与知识总结
2020-11-24 00:25:17参考链接: 第二部分:自动内存管理 ...是线程私有的;生命周期与线程相同 每个方法被执行的时候,Java虚拟机都会同步创建一个栈帧用于存储局部变量表、操作数栈、动态连接、方法出口。每一个方法被调用直至执行 -
【JVM】Java内存区域与内存溢出异常
2020-10-07 18:12:51线程私有,与线程拥有相同的生命周期。 虚拟机栈描述的是Java方法执行的线程内存模型:每个方法被执行的时候,Java虚拟机都会同步创建 一个栈帧用于存储局部变量表、操作数栈、动态连接、方法出口等信息。每一个方法... -
以独占方式锁定此配置文件失败.另一个正在运行_JVM深入解析:运行时数据区+HotSpot+JMM+堆+GC+JVM优化+类...
2020-11-24 02:39:08Java运行时数据区:Java虚拟机在执行Java程序的过程中会将其管理的内存划分为若干个不同的数据区域,这些区域有各自的用途、创建和销毁的时间,有些区域...线程私有的。2、虚拟机栈:虚拟机栈是Java执行方法的内存模... -
JVM内存模型
2019-09-30 16:50:48栈也叫方法栈或者Java虚拟机栈,是线程私有的,程在执行每个方法时都会同时创建一个栈帧,用来存储局部变量表、操作栈、动态链接、方法出口等信息。调用方法时执行入栈,方法返回时执行出栈。 栈帧:... -
Java内存区域与内存溢出异常
2018-08-19 21:07:04线程独占/私有 每个线程都有各自的程序计数器 执行java方法时记录字节码指令地址,执行native方法时为空(Undefined) 虚拟机中唯一一个没有OutOfMemoryError错误的区域 Java虚拟机栈 线程独占/私有 描述Java方法... -
深入理解JVM知识总结
2019-12-26 16:10:24一、 虚拟机 1.1 JVM内存结构模型 主要划分为五个部分:类加载器->运行时数据区->执行引擎->本地库接口->本地方法库 1.1.1 运行时数据区划分 ...虚拟机栈是线程私有的,生命周期和线程一样同... -
JVM的前世今生
2020-07-20 19:04:08JVM是 Java Virtual Machine的简称,俗称Java虚拟机;...线程私有: 虚拟机栈,本地方法栈,程序计数器 当然还有个非JVM管理的 直接内存区域; 栈:是遵循先进后出的数据结构; 一个线程独占一个虚 -
并发基础一
2020-09-07 23:35:11并发基础知识 CPU模型 cpu模型包括ALU,寄存器,主存,高速缓存。 ALU 算数运算单元,运算器 寄存器 主存 ...线程私有:栈、本地方法栈、程序计数器 线程共享:堆、本地方法区 直接内存:直接... -
JVM体系结构
2020-09-21 20:48:393、Java栈、本地方法栈、程序计数器为线程私有区域; 4、程序计数器:程序计数器是一块较小的内存空间,是当前线程所执行的字节码的行号指示器•程序计算器处于线程独占区•如果线程执行的是java方法,记录的是... -
JVM复习之运行时数据区概述及程序计数器
2020-08-24 21:12:58程序计数器、栈、本地栈线程独占。 程序计数器 也叫PC寄存器 作用 存放指向下一条指令的地址。就是将要执行的指令代码。 由执行引擎去读取。 特点 内存小,几乎可忽略,运行速度最快。 每个线程都有自己的程序... -
JVM运行时数据区
2018-10-16 11:57:11线程私有的数据区 --》线程独占区 1.1 程序计数器 --》记录当前线程所执行到的字节码的行号 1.2 虚拟机栈 --》存放方法运行时所需的数据,成为栈帧 1.3 本地方法栈 --》为JVM所调用到的Nativa 即本地方法服务 ... -
JAVA虚拟机(一):内存区域
2019-09-23 22:46:24虚拟机栈,本地方法栈,程序计数器是各线程独占。 概述一下各个区域 先说说线程私有的几个区域: 1.程序计数器 1.当前线程所执行的字节码的行号指示器,通过改变这个计数器的值来选取下一条需要执行的指令。由于... -
Java虚拟机运行时数据区
2020-01-28 23:04:25线程独占区:Java虚拟机栈、本地方法区和程序计数器 (每个线程都有自己的一块区域,线程私有数据区域生命周期与线程相同, 依赖用户线程的启动/结束 而 创建/销毁) 方法区:存储运行时常量池,已被虚拟机加载的类... -
1.JAVA程序运行原理分析
2020-10-27 22:47:39- 虚拟机栈:每个线程都在这个空间有一个私有的空间,线程栈由多个栈帧组成,一个线程会执行一个或者多个方法,一个方法对应一个栈帧。 (例如:当执行main方法时,本地变量表从操作数栈中取出数据并且赋值.) - 本地... -
2020 Java相关面试题整理
2020-05-01 12:14:22线程独占部分:虚拟机栈、本地方法栈、程序计数器 方法区 用来存储加载的类信息、常量、静态变量、编译后的代码等数据 堆内存 用来存放对象的区域,可以细分为:老年代、新生代(Eden、From Survivor、To Survivor)... -
JVM运行时数据区有哪些
2020-09-17 22:19:26JVM运行时数据区 ...每个线程都有一个私有的空间 线程栈由多个栈帧组成。 一个线程会执行一个或者多个方法,一个方法对应一个栈帧。 栈帧内容包括:局部变量表、操作数栈、动态连接、方法返回地址、附加信息 -
java核心知识点整理.pdf
2019-04-19 14:45:24虚拟机栈(线程私有) .................................................................................................................... 22 2.2.3. 本地方法区(线程私有) ................................... -
JAVA核心知识点整理(有效)
2019-03-28 21:36:582.2.2. 虚拟机栈(线程私有) .................................................................................................................... 22 2.2.3. 本地方法区(线程私有) .............................
-
JetBrain 系列软件快捷键集合
-
esp32_https_mbedtls.zip
-
tableSelect联动选择框
-
基于python的dango框架购物商城毕业设计毕设源代码使用教程
-
小白四轮驱动.PcbLib
-
Python OpenCV裁剪并保存图片
-
基于电商业务的全链路数据中台落地方案(全渠道、全环节、全流程)
-
Unlocker.zip
-
数字电影与人工智能结课论文.docx
-
FinTech头条丨祝贺国家电投全球司库管理系统成功上线!
-
Galera 高可用 MySQL 集群(PXC v5.7+Hapro)
-
MySQL DML 语言(插入、更新与删除数据)
-
2021年房屋管理系统源码.rar
-
log(n)怎么理解
-
Java学习日记1注释
-
Java生产实习报告模板 .doc
-
C和C++课程
-
朱老师鸿蒙系列课程第1期-2鸿蒙系统Harmonyos源码架构分析
-
2021-03-03
-
MySQL 视图