JVM解析原理

目录

  • 1.JVM内存结构
  • 2.JIT及时编译器的原理,优化以及切换编译器类型
    • 2.1解释型语言和编译语言
    • 2.2JIT即时编译器(Just In Time Compiler)
  • 3.类的加载机制和类的加载器
    • 3.1类的加载机制
    • 3.2类的加载器
  • 4.双亲委派机制
    • 4.1定义
    • 4.2优点
    • 4.3总结
  • 5.虚拟机栈详解以及栈內存泄露和解决
  • 6.GC垃圾回收机制的介绍和效果演示
    • 6.1finalize()方法
  • 7.对象回收标志-可达性分析
    • 7.1引用计数法
    • 7.2可达性分析
  • 8.垃圾回收算法
  • 9.堆內存的分代管理以及分代垃圾回收算法
  • 10.虚拟机调优和jvisualvm內存追踪工具
  • 11.彩蛋(调整各大参数)

1.JVM内存结构

img

如上图所示, 灰色区域“本地方法栈”,“虚拟机栈”,“程序计数器”为非共享内存,每个Java线程都会开辟独立的运行空间进行运行。而浅蓝色区域“方法区”,“堆”为共享内存区,不同的线程会共享同样一片区域。各版本虚拟机可能会对区域进行优化,比如JDK 1.8中取消了“方法区”,加入metaspace(元数据空间)。

堆:线程共享区

方法区:类的静态属性,方法,类,静态方法,构造方法,接口,常量池,jit编译的东西也在这里

堆:对象,对象的属性

栈:非共享区 每个线程都会创建自己独特的非共享区也就是栈

虚拟机栈

本地方法栈

程序计数器

jdk1.7不单独叫字符串常量池了,就都叫常量池

jdk1.8方法区变成元数据空间,然后把常量池移到堆区了

1.虚拟机栈(线程私有): 这里是我们执行JAVA程序的方法时创建的栈,每个线程对应一个独有的虚拟机栈,每个方法在执行的同时都会创建一个栈帧(栈帧中存储局部变量表,操作数栈,动态链接,方法出口等信息)不存在垃圾回收问题,只要线程一结束该栈就释放,生命周期和线程一致

2.本地方法栈(线程私有):执行native方法时使用的本地栈,该栈的结构并未定义明确的官网规范,所以各虚拟机可以自行开发该栈结构,目前HotSpot中奖虚拟机栈和本地方法栈合并了。

3.程序计数器(线程私有):程序计数器是一块较小的内存空间,它的作用可以看作是当前线程所执行的字节码的行号指示器。在虚拟机的概念模型里字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令,分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖这个计数器来完成。
特点:
1).如果线程正在执行的是Java 方法,则这个计数器记录的是正在执行的虚拟机字节码指令地址
2).如果正在执行的是Native 方法,则这个技术器值为空(Undefined)
3).此内存区域是唯一一个在Java虚拟机规范中没有规定任何OutOfMemoryError情况的区域
4).在任何一个确定的时刻,一个处理器(对于多核处理器来说是一个内核)只会执行一条线程中的指令。因此,为
了线程切换后能恢复到正确的执行位置,每条线程都需要有一个独立的程序计数器,各条线程之间的计数器互不影响,独立存储。

4.堆(线程共享):虚拟机启动时创建,用于存放对象实例,几乎所有的对象(包含常量池)都在堆上分配内存,当
对象无法再该空间申请到内存时将抛出OutOfMemoryError异常。同时也是垃圾收集器管理的主要区域。可通过 -
Xmx1024MB –Xms10MB 参数来分别指定最大堆和最小堆

5.方法区(线程共享):类的所有字段和方法字节码,以及一些特殊方法如构造函数,接口代码也在此定义。简单
说,所有定义的方法的信息都保存在该区域,静态变量+常量+类信息(构造方法/接口定义)+运行时常量池(JDK1.7移
除了字符串常量池),还有JIT编译的代码部分都存在方法区中,虽然Java虚拟机规范把方法区描述为堆的一个逻辑部
分,但是它却有一个别名叫做 Non-Heap(非堆),目的应该是与 Java 堆区分开来。

2.JIT及时编译器的原理,优化以及切换编译器类型

2.1解释型语言和编译语言

解释型语言:逐行解释,同声传译,执行效率低

编译语言:编译执行,整体翻译,执行效率高,但是编译的时间

2.2JIT即时编译器(Just In Time Compiler)

热点数据经过jit即时编译器变成编译语言,把热点代码变成编译语言,不是热点的代码变成解释型语言

最早期的JVM在执行java程序时主要依靠解释型编译器,即对代码行进行逐行解释,每次读取一行程序指令,并通过JVM解释器变成本地机器码进行执行。该解释器的优点是降低了程序的编译的时间成本,但是逐行的解释必然导致执行效率低下。所以后期对JVM进行了优化,加入了程序执行次数计数器(Java中主要使用热点探测技术),对执行的代码段或循环等流程控制结构加入了计数功能,对于那些计数次数超过阈值的代码提出了热点代码的概念。对于非热点代码依然采用解释型执行效果。对于那些热点代码,JVM则使用JIT编译器在编译期将这些代码转换成机器码的方式预先存储在内存中,当用户试图调用该代码段时则无需解释,而是执行预先编译好的机器码,以此加速热点代码的执行效率,所以JIT可以理解成一种实现预编译执行的编译器,因此也说Java属于解释型和编译型共存的开发语言。JIT的加入大大加速了JVM对于程序的执行性能。

img

一些执行参数:

java -Xint或java -Djava.compiler可以关闭JIT解释执行

java -Xcomp 强制只有JIT运行模式

-XX:-TieredCompilation : 强制执行C2编译

-XX:TieredStopAtLevel=1: 强制执行C1编译

JIT编辑结果查看(详细版):

-XX:+UnlockDiagnosticVMOptions

-XX:+LogCompilation

-XX:+TraceClassLoading

-XX:+PrintAssembly

JIT编辑结果查看(内存监测版):

-XX:+PrintCompilation

-XX:+UnlockDiagnosticVMOptions

-XX:+PrintInlining

热点方法探测次数

-XX:CompileThreshold=1000

3.类的加载机制和类的加载器

3.1类的加载机制

img若干个类,一套流程,一套机制

若干个类指若干了类的加载器这样的类,一套流程就是下面哪个,然后一套机制就是双亲委派机制

类的加载过程:加载,链接,初始化,使用,卸载

    详解:先加载这个类,就需要类的加载器参与,之后进行链接,链接就是需要验证一下这个类符合规范不,同时给static修饰的元素分配空间,之后在进行初始化,这个就需要类的构造器了,然后就是使用,最后进行卸载

加载
通过类的全限定名的方式获取class文件的字节流.事实上,加载器可以从任何类型文件(zip,jar,txt等)或者网络中获取class字节流.这个过程需要类加载器参与

链接

将java类的二进制代码合并到JVM的运行状态之中的过程
验证: 确保加载的类信息符合JVM规范,没有安全方面的问题
准备: 正式为类变量(static变量)分配内存并设置类变量初始值(默认值)的阶段,这些操作都在方法区中进行,例如将static int类型的默认值设定为 0,不过对于fifinal类型的静态变量,直接持有原始值。
解析: 虚拟机常量池的符号引用替换为直接引用过程

初始化阶段是执行类构造器()方法的过程。类构造器()方法是由编译器自动收藏类中的所有类变量的赋值动作和静态语句块(static块)中的语句合并产生
当初始化一个类的时候,如果发现其父类还没有进行过初始化,需要先触发其父类的初始化
虚拟机会保证一个类的()方法在多线程环境中被正确加锁和同步
当范围一个Java类的静态域时,只有真正声名这个域的类才会被初始化

3.2类的加载器

启动类加载器:加载jdk下常用的一些工具类 object String(由c语言啥的编写,我们看不到)

扩展类加载器:ext包下的一些类他们的加载 extClassLoader

应用类加载器:主要加载我们自己定义的一些类 AppClassLoader

AppClassLoader这个加载器也是由类加载的,所以是由jdk加载的应用类加载器

img

4.双亲委派机制

4.1定义

双亲委派机制是JVM类的加载过程中比较重要的机制,即无论由什么加载器进行当前类的加载当前类,则都不会进行直接加载,而是先向其父加载器申请加载请求,由父加载器委派进行,其机制如下:

例如:用户创建了一个MyType试图进行加载,其步骤如下: 
1. 首先使用应用类加载器(AppClassLoader)进行判定,如果此类已经被加载,则直接返回,如果未加载则进行
2. 使用扩展类加载器(ExtClassLoader)从当前规定路径下进行判定,如果已加载则直接返回,如果未加载则向上委托给启动类加载器进行加载

3. 启动类加载器从rt.jar中进行查找,如果已加载则直接返回,如果未加载则从启动类加载器规定路径下查找该
  类,如果找到则进行加载直接返回,如果未找到则指派给扩展类加载器进行加载。
4. 扩展类加载器从当前规定路径下进行加载,如果加载成功直接返回,如果未成功则指派给应用类加载器进行
  加载
5. 应用类加载器从规定路径下加载该类,若加载成功则返回该类,如果未成功则产生ClassNotFoundException
  异常,终止查找步骤。

4.2优点

优点:
(1)可以最大限度避免因为用户自定义类的全限定名和系统提供的核心类的权限定名冲突而导致的重复加载出错
的问题。
(2)为了安全机制考虑,避免因为提供了一些和系统重名的自定义类破坏系统安全性的问题
缺点:
从加载过程不难看出双亲委派机制虽然提升了安全性,但是缺降低的类的加载速度并且提升了加载过程的复杂程
度,不过相对于安全性考虑,这些性能的牺牲是值得的。

4.3总结

双亲委派机制是JVM类的加载过程中比较重要的机制,即无论由什么加载器进行当前类的加载当前类,则都不会进行直接加载,而是先向其父加载器申请加载请求,由父加载器委派进行,先问应用加载器加载了没,然后没加载,往上问ext扩展类加载器加载了没,没加载,再问终极启动类加载器加载了没,ok没加载,然后在启动类加载器中看自己能不能加载这个类,不能的话就问ext扩展类加载器能不能加载,也不能直接过,最后在看应用类加载器,ok可以加载,这就是双亲委派机制

加载类是用的全限定名,如果自己写的类和系统的启动类Object全限定名 java.lang.Object重名了,那么系统会加载自己的类而不是你的类,从而保护了系统的安全,这就是双亲委派机制的优点

双亲委派机制的优缺点 :

安全性高 避免重名类(全限定名一样)对系统的影响

缺点是加载速度变慢

5.虚拟机栈详解以及栈內存泄露和解决

1.每个线程在执行的时候,就会产生自己独特的虚拟机栈的结构,每次执行一个方法的时候,就会压入一个栈帧,栈帧里面有局部变量表,操作数栈,动态链接,方法出口。(虚拟机栈是虚拟机线程执行时创建的私有空间,每次该线程执行方法时都会产生一个栈帧,其中包含局部变量表,操作数栈,动态链接,和方法出口四个组成部分。虚拟机栈就是我们日常所说的关于栈、堆结构中的栈结构。)

2.虚拟机栈特点:

虚拟机栈是线程私有的,即每个线程都有自己独立的虚拟机栈

3.虚拟机栈的StackOverflowError

可以通过-Xss10M 就是改成10M的大小用来存储栈帧的空间大小也就是栈的内存大小

代码是一行一行执行的,每执行完一个方法就会弹出那个栈帧,但是一个方法中又调用了另一个方法,就会一直压入栈帧,导致栈溢出

4.虚拟机栈的OutOfMemoryError

帧占用空间大小达到了上限而产生的错误信息。JVM并未提供单独设置虚拟机栈默认最大内存的方法,但是它的大小可以约等于JVM所允许的最大内存容量,即JVM允许的最大内存越大,虚拟机栈的容量上线越高。我们可以通过占用较大内存空间的局部变量来进行模拟,代码如下

img

6.GC垃圾回收机制的介绍和效果演示

GC Garage Collection 垃圾回收器 堆内存

常规的简单对象 引用如果不再指向该对象的话,那么该对象就可以被回收

6.1finalize()方法

这个方法是当对象被垃圾回收器回收时会执行的方法,就是说当垃圾被回收了,就会执行这个方法,就是说这个方法执行了就可以判断垃圾回收了,我们可以重写这个方法,当对象被回收了,这个方法的内容就会被显示出来

我们通常用的对象一段时间不用就可以被回收啦,但是我们要尽快让为null或者长时间不用的对象区回收的话,就用System.gc();这个方法可以提示垃圾回收器尽快的启动去回收垃圾对象

垃圾回收机制是不确定的

垃圾回收机制执行的时候会STW ,所有的java程序都会被中断,所以不要频繁的使用System.gc();,他自己启动的时候只会在他不忙的时候启动

7.对象回收标志-可达性分析

7.1引用计数法

最开始的垃圾回收技术是引用计数法:当你产生这个对象的引用的时候,计数器加一,然后引用回收的时候减一,达到0的时候就可以回收啦~

引用计数法存在缺陷,当两个对象相互作为对方属性的时候,难以销毁,所以java用的可达性分析法来回收对象

7.2可达性分析

GC Roots GC根

任何一个对象判断它是可回收对象,需要判断没有任何一条路径能到达它的GC Roots

可以当做GC Roots的量

a.局部变量

b.static类型的属性

c.常量final

d.native方法

eg:A里面存储了一个B对象 B里面存储了一个A对象

img

eg:B是一个普通对象,C里面存储了一个B对象static的属性

然后C c = new C();

B b = new B();

c.b = b;

c = null;

b = null;

System.gc();

因为b的直接引用存储在了gcroots中指向了B对象, 又来了一个static修饰的属性存储在gcroots指向了B对象,所以当b=null的时候,gcroots面还有一个静态属性的引用指向B对象,所以B对象不可以回收

8.垃圾回收算法

标记消除法:(在原空间操作)

优点:清除元素的效率比较高,

缺点:空间利用率

复制算法:(新开辟一个空间)

在整一个空间用于复制刚才消除对象之后形成的空格键

优点:空间利用率高,

缺点:二倍內存开销,回收效率略低,

如果要提升复制算法的回收效率,那么高频回收的对象比较适合这种算

标记压缩法:(在原空间操作)

优点:既保证了内存连续,也不会产生二倍的内存开销

缺点:回收效率比较低,

如果希望提升标记压缩法的效率,那么回收的对象越少越好

9.堆內存的分代管理以及分代垃圾回收算法

img

9.1分代管理
堆内存会把区域分为年轻代和老年代

內存分配比例:

老年代:年轻代-----------> 2 : 1 可以用这个参数来调整-XX:NewRatio = 2,老年代必须是多的 所以最小值是1

eden:from:to --------------> 8:1:1 可以用这个参数来调整-XX:SurvivorRatio = 8,from和to必须一样

年轻代:新创建的对象,在年轻代里面进行垃圾回收就叫轻GC
两个区

eden区 :Java程序最开始new的所有对象,eden区堆满了就会进行minor GC

survial区

    from(s0):

    to(s1)

总结:

程序刚开始的时候,会创建对象,进入eden区,如果eden区满了,就要回收对象,用可达性分析法,就会进行轻gc,这必然存在有的对象没有被回收,然后就会从eden区进入survial区,进入from里,to里没东西(from和to用的垃圾回收算法是复制),每次进行gc的时候,eden区和survial都会进行垃圾回收,然后from里永远是存东西的那个,而to不存东西,他俩可以进行名字交换,每次捣登的时候年龄都会+1,例如从eden区往from里面捣登,它就变成1岁了,第二次eden区满了,然后进行垃圾回收,eden区剩余的,和survial区里面的from里面的,都会进行可达性分析,最后在进入survial里面剩余的空白那个位置,然后空白的名字变成from,没东西那个叫To,上次在survial中的没被回收的对象岁数继续+1,最大岁数也就是15岁,如果from里面的对象活到了15岁,就让去老年代那个区区养老了。

老年代:存活时间比较长的对象
老年代不受minor GC的影响,老年人堆满了之后,触发Full GC 或者叫 major GC,触发Full GC的话,堆整体都要进行一下垃圾回收,所以full GC非常的消耗资源

System.gc()就是强制启动FULL GC

分代回收
所谓分代回收就是不同的代用不同的垃圾回收机制,年轻代用minor GC 轻GC,老年代用fullgc majorGC

10.虚拟机调优和jvisualvm內存追踪工具

minor GC 和 major GC都会产生STW

stop the world 进行垃圾回收的时候,就会进行stw 然后系统执行效率会变慢

full GC 对系统的影响是远大于minor GC的,所以虚拟机调优就是尽量的减少full GC

动态年龄判断:就是说当suvial中虽然对象的年龄没有达到15岁,进不去老年代,但是form內存满了,就得用动态年龄判断,实际开发就需要用那个工具

大对象:eden剩余的单一的一个大对象太大了 大于s0和s1直接就进入老年代

对象群:就是经过一次轻minor gc之后剩余的对象大于s0和s1的存储上限

每次进行轻GC之前都要进行內存分配担保

虚拟机调优主要就是看哪些参数还有就是内存分配担保的条件啥的(增大老年和新生代的比例)

11.彩蛋(调整各大参数)

参数的设置

-Xss用来设置栈内存大小

-Xmx:最大值 :当前给虚拟机分配的最大内存->java程序占用的总内存,包含堆

-Xms:最小值:初始的时候目前允许占用的最大值

老年代:年轻代-----------> 2 : 1 可以用这个参数来调整-XX:NewRatio = 1,老年代必须是多的 所以最小值是1

eden:from:to --------------> 8:1:1 可以用这个参数来调整-XX:SurvivorRatio = 1,from和to必须一样

-XX:MaxTenuringThreshold=15这个是修改几岁才进入老年化

-XX:TargetSurvivorRatio=50% 也可以设置一下动态数值,这个数值是form里面数据量大于50%就要把大于的那些年龄段的都给整进老年人队伍

-XX:PretenureSizeThreshold=10M 大对象 eden里面剩余的单个对象对象太大 大于s0和s1直接就进入老年代

虚拟机的堆内存使用是迭代式的,因为不想占用太多的內存,但是实际开发最好是两个值相等

img

上面的代码是计算堆中占用的总内存和目前允许占用最大值和剩余最大值,如果Xmx和Xms相等的话,上面的代码max和total也是相等的

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

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

相关文章

读破万卷,神交古人,突破ChatGPT4096的Token限制,建立自己的垂直领域资料人工智能助理

ChatGPT的泛用性极高,上知天文,下通地理,参考古今,博稽中外,几乎无所不知,无所不晓。但如果涉及垂直领域的专业知识点,ChatGPT难免也会有语焉不详,闪烁其词的毛病,本次我…

16从零开始学Java之Java里的输入与输出语句有哪些?

作者:孙玉昌,昵称【一一哥】,另外【壹壹哥】也是我哦 CSDN博客专家、万粉博主、阿里云专家博主、掘金优质作者 前言 我们在前面的文章中,学习了如何创建Java文件,也学习了Java里的标识符、运算符、进制等内容。有些…

iPhone手机小技巧:使用备忘录创建清单

手机备忘录是非常常用的软件之一,无论是iPhone手机还是安卓系统的手机都可以下载相应的APP进行使用。它可以帮助我们记录很多琐碎的事情,防止我们遗忘某事。 在记备忘录的时候,有的人是直接打字记录的,也没有什么具体的格式&…

Excel–如何区分大小写、精确匹配查找?

最近经常需要用到uuid来匹配数据,经常会遇到两个uuid 只是大小写的区别,数据库里使用是没问题的,因为mysql是可以区分大小写的,但是导出后通过excel处理数据匹配数据时就会出问题 如下图所示,通过vlookup匹配&#xf…

文心一言 VS chatgpt (3)-- 算法导论2.1

一、以图 2-2 为模型,说明INSERTION-SORT 在数组 A(31,41,59,26,41,58)上的执行过程。 文心一言: 以图 2-2 为模型,说明INSERTION-SORT 在数组 A(31,41,59&…

Java基础学习第二十四讲:Stream流

Stream流 一、什么是Stream流 Stream流操作是Java 8提供一个重要新特性,它允许开发人员以声明性方式处理集合,其核心类库主要改进了对集合类的 API和新增Stream操作。Stream类中每一个方法都对应集合上的一种操作。将真正的函数式编程引入到Java中&…

ROS功能包|mav_control_rw(基于MPC的无人机轨迹跟踪控制)---gazebo仿真测试

ROS功能包|mav_control_rw(基于MPC的无人机轨迹跟踪控制)---gazebo仿真测试gazebo仿真测试gazebo仿真测试 启动gazebo并加载无人机模型 $ roslaunch rotors_gazebo mav.launch mav_name:firefly启动 linear mpc 控制器 $ roslaunch mav_linear_mpc ma…

Win10安装MySql1.5.7

1)、下载安装包 地址:MySQL :: Download MySQL Community Server 或者: 链接:https://pan.baidu.com/s/1iSLiUo8ehqP6tfxGJ2ewfA 提取码:ctbr 2)、下载后解压到指定目录 我的是D:\Program Files\mysql-…

SCS【19】单细胞自动注释细胞类型 (Symphony)

单细胞生信分析教程桓峰基因公众号推出单细胞生信分析教程并配有视频在线教程,目前整理出来的相关教程目录如下:Topic 6. 克隆进化之 CanopyTopic 7. 克隆进化之 CardelinoTopic 8. 克隆进化之 RobustCloneSCS【1】今天开启单细胞之旅,述说单…

一图看懂 bz2 模块:处理压缩和解压缩文件, 资料整理+笔记(大全)

本文由 大侠(AhcaoZhu)原创,转载请声明。 链接: https://blog.csdn.net/Ahcao2008 一图看懂 bz2 模块:处理压缩和解压缩文件, 资料整理笔记(大全)摘要模块图类关系图模块全展开【bz2】统计常量int模块4 io5 os6 warnings7 _compre…

数据结构与算法基础(王卓)(23):邻接表(链式存储结构)

顶点结点: //顶点的结点结构 typedef struct VNode {VertexType data; //顶点信息ArcNode* firstarc; //指向第一条依附该顶点的边的指针 }VNode, AdjList[MVNum]; //例如:VNode v[MVNum] 相当于 AdjList v 我觉得也可以改成这样写(存疑&…

基于数字孪生智慧污水厂Web3D可视化管理系统

城市水环境不仅关系到国民生活的质量,还对我国社会发展有着深入的影响。城市污水处理厂的存在不仅能够提升生态环保工作发挥的效用,还能够向城市居民宣传生态环保的重要性,使得更多的市民认识到节约、环保的意义,能够从自身出发&a…

UVM学习笔记2——验证基础知识(验证计划、验证方法)

文章目录前言一、覆盖率二、验证计划1、验证计划模板2、验证计划评估三、验证方法1、动态仿真/dynamic simulation2、静态检查/formal check3、虚拟模型4、硬件加速/hardware acceleration5、效能验证6、性能验证四、验证分类1、验证工具2、验证复杂度/可见度/透明度3、验证的芯…

Java设计模式(一)单例模式

设计模式是对软件设计中普遍存在的各种问题,提出解决方案 设计模式包含了面向对象的精髓,懂了设计模式,你就懂了面向对象分析和设计的精要。 设计模式的七大原则 1.单一职责原则 2.接口隔离原则 3.依赖倒置原则 4.里氏替换原则 5.开闭原则o…

大数据项目实战之数据仓库:用户行为采集平台——第2章 项目需求及架构设计

第2章 项目需求及架构设计 2.1 项目需求分析 1)采集平台 (1)用户行为数据采集平台搭建 (2)业务数据采集平台搭建 2)离线需求 主题 子主题 指标 流量主题 各渠道流量统计 当日各渠道独立…

pdf压缩文件怎么压缩最小?办公常备软件

PDF文件的大小有时会让人感到困扰,特别是在网络上传输和存储方面。为了解决这个问题,我们需要将PDF文件压缩至最小。 在进行压缩之前,需要检查PDF文件的分辨率和图形质量。通过降低分辨率和图形质量,可以显著减小文件的大小。此外…

springCloud学习【6】之分布式搜索引擎(3)

文章目录前言一 数据聚合1.1 DSL实现聚合1.1.1 Bucket聚合语法1.1.2 聚合结果排序1.1.3 限定聚合范围1.2 Metric聚合语法1.3 小结1.4 RestAPI实现聚合1.5 API语法1.7 案例二 自动补全2.1 拼音分词器的安装2.2 自定义分词器2.3 自动补全查询2.4 自动补全查询的JavaAPI三 数据同步…

Unity升级后打包AssetBundle变慢

1)Unity升级后打包AssetBundle变慢 ​2)打包使有些资源合成了一个资源data.unity3d,有些分开的原因 3)Unreal在移动设备中无法使用Stat命令获取到GPU Thread的耗时 4)Unity中如何看到相机视野范围内的剔除结果 这是第3…

【C++】迭代器

内容来自《C Primer(第5版)》9.2.1 迭代器、9.2.3 begin和end成员、9.3.6 容器操作可能使迭代器失效、10.4.3 反向迭代器 目录 1. 迭代器 1.1 迭代器范围 1.2 使用左闭合范围蕴含的编程假定 2. begin和end成员 3. 容器操作可能使迭代器失效 3.1 编…
最新文章