共计 7038 个字符,预计需要花费 18 分钟才能阅读完成。
在很多的场合我都遇到过一些群友提这样的一些问题:
为什么 Java 有 GC 调优而 CLR 没有据说过有 GC 调优呢?到底是 Java 的 JVM GC 比拟强还是 C# 应用的.NET CLR 的 GC 比拟强呢?其实业内曾经有几位大佬的高赞文章和大家分享一下,次要探讨 JVM 和 CLR 还有 GC 调优,明天就借用大佬的答复给大家分享一下。
R 大的答复
https://www.wenjuan.com/s/UZB…
https://www.wenjuan.com/s/UZB…
https://www.wenjuan.com/s/UZB…
https://www.wenjuan.com/s/UZB…
https://www.wenjuan.com/s/UZB…
https://www.wenjuan.com/s/UZB…
https://www.wenjuan.com/s/UZB…
https://www.wenjuan.com/s/UZB…
https://www.wenjuan.com/s/UZB…
https://www.wenjuan.com/s/UZB…
https://www.wenjuan.com/s/UZB…
https://www.wenjuan.com/s/UZB…
https://www.wenjuan.com/s/UZB…
https://www.wenjuan.com/s/UZB…
https://www.wenjuan.com/s/UZB…
https://www.wenjuan.com/s/UZB…
https://www.wenjuan.com/s/UZB…
https://www.wenjuan.com/s/UZB…
https://www.wenjuan.com/s/UZB…
https://www.wenjuan.com/s/UZB…
https://www.wenjuan.com/s/UZB…
https://www.wenjuan.com/s/UZB…
https://www.wenjuan.com/s/UZB…
https://www.wenjuan.com/s/UZB…
https://www.wenjuan.com/s/UZB…
https://www.wenjuan.com/s/UZB…
https://www.wenjuan.com/s/UZB…
https://www.wenjuan.com/s/UZB…
https://www.wenjuan.com/s/UZB…
https://www.wenjuan.com/s/UZB…
https://www.wenjuan.com/s/UZB…
https://www.wenjuan.com/s/UZB…
https://www.wenjuan.com/s/UZB…
https://www.wenjuan.com/s/UZB…
https://www.wenjuan.com/s/UZB…
https://www.wenjuan.com/s/UZB…
https://www.wenjuan.com/s/UZB…
https://www.wenjuan.com/s/UZB…
https://www.wenjuan.com/s/UZB…
https://www.wenjuan.com/s/UZB…
https://www.wenjuan.com/s/UZB…
https://www.wenjuan.com/s/UZB…
https://www.wenjuan.com/s/UZB…
https://www.wenjuan.com/s/UZB…
https://www.wenjuan.com/s/UZB…
https://www.wenjuan.com/s/UZB…
https://www.wenjuan.com/s/UZB…
https://www.wenjuan.com/s/UZB…
https://www.wenjuan.com/s/UZB…
https://www.wenjuan.com/s/UZB…
https://www.wenjuan.com/s/UZB…
https://www.wenjuan.com/s/UZB…
https://www.wenjuan.com/s/UZB…
https://www.wenjuan.com/s/UZB…
https://www.wenjuan.com/s/UZB…
首先给大家介绍一下 R 大,R 大网名叫 RednaxelaFX,南京大学毕业巨佬,主攻高级编程语言虚拟机的设计与实现,对于 C# .NET CLR 有十分深刻的钻研和理解。先后退出阿里、Oracle、Azul System 从事 JVM 虚拟机开发的工作(HotSpot JVM and Zing JVM)。当初在 Databricks 从事 Spark 开发工作。
这里 R 大次要就 CLR 上几种调优形式和为什么 CLR 不须要 xmx、xmn 等参数给出了起因
因为题主您就是没听说过 >_<
假设题主说的是上面三个层面的调优的头两种状况:
对 VM 的配置参数调优(例如 GC 参数)对应用程序本身的代码调优
对 VM 本身的实现调优
(2) 的话无论什么语言什么环境都好,谋求性能的人必定都有在做。Java 和.NET 都有好用的 profiler 能够帮忙这方面的考察和调优。
有时候参数调优还不够的中央,也只能本人改本人的利用代码来解决问题了。请看一个经典案例:
In managed code we trust, our recent battles with the .NET Garbage Collector
(3) 的话,CLR 还没开源的时候,也无从调起。倒是有不少人给 Mono 奉献改良性能的 patch,也算是狭义上“.NET”的 VM 实现层面调优吧。
在 CoreCLR 开源后,也有不少人给 CoreCLR 奉献各种 patch 呢,包含“调优”。
.NET 码农们以前时不时会中招的一种中央是程序进入 GC 的耗时(time-to-GC),也就是从 CLR 说“我要开始做 GC 了”到“真正开始做 GC”之间的耗时。这里次要开销来自申请所有利用线程暂停(SuspendEE),这些线程要多久才实现对该申请的响应。据说过这个过程中会产生“250ms 的倍数的等待时间”不?请跳传送门:
Garbage Collection Thread Suspension Delay (250ms Multiples)
像这种问题就是不进到 VM 外部做批改的话无奈解决的。
(1) 的话,其实就算当年 CLR 还没开源的时候,CLR 也是有调优参数能够配置的呢。
最经典的就是抉择试用 Workstation GC(WKS GC)或者 Server GC(SVR GC)。见过 <gcServer> 参数不?
起初能够配置应用 Concurrent GC、Background Workstation GC、Background Server GC 等。
用户还能够在代码里通过 GCSettings.LatencyMode 属性来影响 GC 的行为。
看,调优参数列表之一:
Runtime Settings Schema
不过 CLR 跟 HotSpot VM 在配置上有一个显著的区别,就是 CLR 不须要用户指定一个“GC 堆的最大大小”。这跟 CLR 的 GC 堆的根底设计思路有关系。
HotSpot VM 的 GC 堆肯定要应用间断的虚拟地址空间。VM 在启动的时候会一口气 reserve GC 所须要的整个地址空间,而后再按需 commit。-Xmx 会参加到 GC 堆最大大小的计算中。
CLR 的 GC 堆则是分段式的(segemented),GC 堆所用的空间会一个个 segment 调配,用满了一个再去调配一个新的;segment 不须要在间断的地址空间上。这样 GC 堆能够按需主动增长或者缩减,能够始终增长到耗尽虚拟地址空间或者达到配额。
CLR 这种分段式 GC 堆的益处是,在 Windows 上,特地是 32 位 Windows 上,虚拟地址空间中用户程序能够用的局部是比拟系统的,想要用到尽就不能对“间断的地址空间”有太多要求,这种条件下 CLR 跑在 Windows 上就能够充分利用资源。
而且这样一来,用户就不必头疼实现想好要配置多大的堆给 CLR 用了。反正它须要用多少会本人去增长。这用户体验就比搜索枯肠想个好 -Xmx 要爽。
这种做法的害处…怎能没有害处呢。害处也有若干。其中一个就是在这样的堆上实现的分代式 GC 的 write barrier 效率会比 HotSpot 那种用间断地址空间的要差一些。而且 segmented heap 实现起来也略微简单一些。
CLR 相比 JVM 有哪些先进之处?
CLR 相比 JVM 有哪些先进之处?– RednaxelaFX 的答复 – 知乎 https://www.zhihu.com/questio…
这里 R 大次要介绍了下 CLR 和 JVM 的不同,和上面 hez 大佬的答复能够对应起来
尽管只写了一半但还是先收回来省得坑掉。前面边探讨边更新吧…
这个问题原文是:
CLR 相比 JVM 有哪些先进之处?
留下备份。
首先这个问题按其原样无法回答,因为 CLR 与 JVM 不是可比拟的对象。
CLR(Common Language Runtime)是 CLI(Common Language Infrastructure)标准中的 VES(Virtual Execution System)的一种具体实现,而“JVM”不指定实现的话只能说是一种形象的标准。
适宜比拟的对象是:
标准层面:CLI vs JVM
实现层面:CLR / Mono 等 vs HotSpot VM / J9 VM / JRockit VM 等
从标准层面看的话,CLI 标准
ECMA-335
以后最新的版本是 2012 年出的第 6 版。我没太跟进新的 CLI 标准所以不确定这个版本的 CLI 与哪个版本的.NET Framework 里的 CLR 对应。
JVM 标准
The Java® Virtual Machine Specification
以后最新的版本则是 2015 年出的 Java SE 8 版。
在标准层面上,以后的 CLI 完胜以后的 JVM。
《Virtual Machines: Versatile Platforms for Systems and Processes》
一书中有一章专门比照介绍了 CLI 与 JVM 的设计,值得一读。
JVM 标准由 Sun 最后的 JVM 实现(起初称为 Classic VM)形象而来,而后简直没有大的改变。起初的更新次要增加了 Class 文件对泛型信息的无限记录、注解(annotation)反对、字节码校验器的更新(split verifier / type checking verifier)、invokedynamic 及 MethodHandle 反对、default method 反对等。
最后的 JVM 标准尽管也提到它“能够反对多种语言”,但次要目标还是反对 Java 一种语言的执行,直到 Java 7 增加了 JSR 292(invokedynamic 与 MethodHandle)后才有了专门为 Java 以外的语言设计的性能。
CLI 由.NET 最后的 CLR 实现形象而来,而后与 CLR 一起逐步进化。它呈现的工夫毕竟比 JVM 标准晚许多,而且一开始就以反对多种语言、多种范型的执行与互操作为设计目标,天然设计得更欠缺。对历史有趣味的同学能够搜搜“Project 7”看。
Interviewer: I’ve heard that there was a project where Microsoft started to inte…
Don Syme: That’s a small part of the sequence. The visional design of the .NET platform was very much expected to be a multi-language platform from the start. Right back in 1998, just in fact as our research group in programming languages started at Microsoft and I joined the team and then other 10 of us joined the team, we were approached by a guy called James Plamondon, who started the project called Project 7, which was about getting 7 academic and 7 industrial programming languages on each side to target the .NET common language runtime and really check out if it was good enough, to see if design changes could be made early on in the design process of .NET to make sure it was good enough for a range of programming languages.
Project 7 的参与方尝试了将许多种语言移植到 CLR 上,包含 C、Pascal、Cobol (Fujitsu)、Fortran (Salford)、Haskell、Standard ML、Eiffel、Active Oberon for .NET (ETH)、Gardens Point Component Pascal (QUT) 等等。
起初还有更进一步的“Project 7+”。
Technical Overview of the Common Language Runtime
要追寻 CLR 更早的黑历史就不得不提微软的 Visual J++。请跳传送门:
微软当年的 J++ 到底是什么?为什么 Sun 要告它?– RednaxelaFX 的答复
上面先列举一些点揭示我回头更新…
Assembly vs Class 文件
常量池以 stream 的形式存在
能够有 strong name
CIL(Common Intermediate Language)/ MSIL vs Java 字节码
CIL 不仅有二进制模式的标准,而且还有规范的文本模式语法;Java 字节码只有二进制模式的标准
局部变量区里无论什么类型的值都应用 1 个 slot,而 JVM 则是 long 和 double 用相邻的 2 个 slot
异样解决反对 filter
反对具现化泛型(reified generics)OpenJDK: Valhalla
泛型反对申明点协变 / 逆变(declaration-site variance)Java 语言层面的泛型则是反对应用点协变 / 逆变(use-site variance)反对无符号整数类型(unsigned)反对用户自定义值类型(value type)OpenJDK: Valhalla
反对对用户自定义值类型指定显式内存布局,能够模仿 C 的 struct 和 union 以便互操作(StructLayout)OpenJDK: Panama
反对查看溢出的算术运算(checked arithmetic)反对有保障的尾调用(tail call)反对 unsafe verifiable 代码
反对轻量代码生成(LCG,Lightweight Code Generation)反对委托类型(Delegate / MulticastDelegate)CLI Delegate 的 single cast 版本与 Java 7 的 MethodHandle 有相似之处
反对不便的 P /Invoke 和 Reverse P/Invoke
OpenJDK: Panama
不反对自定义类加载器(custom class loader)。JVM 上过于灵便的 ClassLoader 几乎是头疼的要命,不反对这个几乎好。
CLI 里藏的私货:Assembly 采纳 PE(Portable Executable)格局。PE 是 Windows 上原生的可执行文件格局。
CLR 与 Windows 的整合
Windows Loader 能够间接辨认.NET Assembly 并启动 CLR 来执行程序。Windows 对 GAC(Global Assembly Cache)有文件系统层面的非凡解决,“Fusion”。与 COM 有良好的互操作能力。毕竟 CLR 本来就是心愿设计成下一代 COM,本来还用过 COR 这个名字(COM Object Runtime)。分块式 GC 堆(Chunked GC Heap),能够主动扩张和膨胀 GC 堆的大小,并且在 Windows 这种地址空间比拟破碎的环境中能够无效的利用地址空间里的空隙。对应的,JRockit 在 Windows 上则是用 filler object 来利用空隙。GC 堆分为多个空间,特地是高频堆 / 低频堆(high-frequency heap / low-frequency heap)的划分很乏味。GC 反对固定住对象(Object Pinning)GC 提供 API 让应用程序能够指定 native 对象的内存压力,以便 GC 与 native 协调工作(System.GC.AddMemoryPressure Method (Int64))反对 Windows 的结构化异样解决(SEH)。
CLR 与 一些 JVM 实现之间有对应物的
CLR:DAC / SOS 扩大;HotSpot VM:Serviceability Agent;J9 VM:DTFJ / jdmpview
CLR:CAS(Code Access Security)与 JVM 的沙箱