1
Jooooooooo 2020-12-15 14:49:35 +08:00
.net 不用设置内存大小吗
|
2
Jooooooooo 2020-12-15 14:51:05 +08:00
假设有一天
你写了个很挫的代码, 不小心内存使用扩大了十倍 让你找下原因 这就是 jvm 的题目 所以 .net 没有这种问题是吗? 真的吗, 我不信.jpg |
3
enihcam OP |
4
Jooooooooo 2020-12-15 14:52:31 +08:00
我搜了一下, .net 也是有 GC 和 stw 的
那么有一天, 你发现线上的 stw 时间翻了一倍, 让你找下原因 这就是调优 还是你说 .net 不会有这种问题 |
5
Jooooooooo 2020-12-15 14:53:21 +08:00
@enihcam 所以你申请一个机器假设 16G, 要用到都开始 swap 了才能发现有问题?
|
6
enihcam OP @Jooooooooo .net 有 profiler 啊,visual studio 自带的就异常强大。这么说 java 找内存泄漏是件很困难的事情。
|
7
MinQ 2020-12-15 14:54:09 +08:00
@Jooooooooo dot net 可以使用系统中所有可用内存
|
8
Jooooooooo 2020-12-15 14:55:14 +08:00
@enihcam 你说的那个 profiler 就是调优. 为啥看不起别人同样的东西呢?
|
9
enihcam OP @Jooooooooo 怎么可能 swap,内存达到一定级别,容器检测就把你干掉了。
|
10
enihcam OP @Jooooooooo profiler 调的是业务代码吧我理解,我质疑的是 JVM 参数调优。
|
11
Jooooooooo 2020-12-15 14:56:49 +08:00
|
12
Jooooooooo 2020-12-15 14:57:18 +08:00
@enihcam 是啊. 这些问题都是通用的, 为啥在 java 上调整就要遭人鄙视呢?
|
13
MinQ 2020-12-15 14:57:36 +08:00 1
@Jooooooooo profiler 不是调优,是类似 Memory Analyzer Tool 一样的工具,用来实时监控程序里面各个对象的资源占用的
|
14
Jooooooooo 2020-12-15 14:58:06 +08:00
|
15
Jooooooooo 2020-12-15 14:58:45 +08:00
@MinQ 对啊. 用 MAT 也是 jvm 调优的一项. 你也说了是类似的, 那这个问题在于?
|
16
enihcam OP |
17
enihcam OP @Jooooooooo 文中提到 JAVA_OPTS="$JAVA_OPTS -server -Xms3G -Xmx3G -Xss256k -XX:PermSize=128m -XX:MaxPermSize=128m -XX:+UseParallelOldGC -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/usr/aaa/dump -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Xloggc:/usr/aaa/dump/heap_trace.txt -XX:NewSize=1G -XX:MaxNewSize=1G"
这是什么奇怪的东西?是 JVM 调优吗? |
18
hello2060 2020-12-15 15:02:29 +08:00 via iPhone 1
@Jooooooooo 这不算调优吧?就像 C++程序写的有内存泄漏一样,那叫修 BUG 也不叫性能调优啊
|
19
Jooooooooo 2020-12-15 15:04:40 +08:00
@enihcam 这就是设置内存大小, GC 算法, 打印日志开关, dump 文件放哪.
|
20
Jooooooooo 2020-12-15 15:05:13 +08:00
@hello2060 那 jvm 调优就是干这些事情. 所以我说你们对 jvm 调优有不切实际的认知.
|
22
MinQ 2020-12-15 15:05:51 +08:00
@Jooooooooo JVM 需要调优是因为它是 VM 啊,代码是在 VM 上运行的。CLR 又不是 VM,代码先被转换成 MSIL 中间语言,然后就被 JIT 编译器编译成当前平台的字节码了,直接跑在操作系统层面上
|
23
micean 2020-12-15 15:06:23 +08:00
绝大部分 java 码农也不关心 jvm 性能啊。。。。。。最多也就查个内存泄漏
|
25
liudaolunhuibl 2020-12-15 15:08:28 +08:00
感觉就是八股。。实际上用到过 jvm 调优的人很少的,最多就是 dump 下线程或者堆,然后 jvm 参数就是换个垃圾回收器加大一下堆大小仅此而已,而且这些事情一般都是团队的“架构师”做,一般的 CRUD BOY 是接触不到的。面试的时候背就完事儿了
|
26
FreeEx 2020-12-15 15:11:13 +08:00
如果互黑的话就是因为 .Net 的网站用户量太小。
认真点就是高级工程师都需要知道如何优化系统运行效率,排查系统占用高,响应慢的原因,所以 Java 工程师就需要对 Jvm 有深刻的了解。 .NET 肯定也是需要的,不然你怎么排查? |
29
MinQ 2020-12-15 15:16:17 +08:00
@liudaolunhuibl 起码 OOM 还是要看一眼的,不是无脑加堆就完事了
@FreeEx dot net 当然也需要,profiler 就是帮忙干这事的,但 dot net 不太会出现由于 CLR 参数设置不合理导致出问题,一般都是自己的问题或者 framework 中有 bug |
30
liudaolunhuibl 2020-12-15 15:18:11 +08:00
@MinQ 我没说吗?最多就是 dump 下线程或者堆
|
32
Rwing 2020-12-15 15:18:40 +08:00 6
知乎上有人问过了,建议看看大佬的回答 https://www.zhihu.com/question/52900051
|
35
FreeEx 2020-12-15 15:42:46 +08:00
@MinQ 当你需要在某一个操作系统运行多个程序,又不想某一个程序把内存占满的情况下是需要限制程序使用的内存的,Jvm 可以帮你限制。当然一台机器一个程序完全不用限制。
当你想要压榨机器的性能,因为在 Jvm 里面类,方法,变量,对象等元素是存在不同的地方的,可以根据当前项目的实际情况调整每一个地方的大小,这样便可以增加程序可处理的请求。当然,钱多加机器可解。 这些在开发的时候基本上无需考虑,算是技术经理才需要想的问题吧。 |
37
a719031256 2020-12-15 15:46:56 +08:00
面试需要呗,反正我遇到的项目从开发到上线再到运营就没遇到 jvm 调优
jvm 这东西默认值就能满足 95%的需求了 |
38
MapHacker 2020-12-15 15:50:55 +08:00 2
把大佬的回答直接粘过来吧
作者:RednaxelaFX 链接: https://www.zhihu.com/question/52900051/answer/132583244 来源:知乎 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 假定题主说的是下面三个层面的调优的头两种情况: 1.对 VM 的配置参数调优(例如 GC 参数) 2.对应用程序自身的代码调优 3.对 VM 自身的实现调优 (2)的话无论什么语言什么环境都好,追求性能的人肯定都有在做。Java 和.NET 都有好用的 profiler 可以帮助这方面的调查和调优。有时候参数调优还不够的地方,也只能自己改自己的应用代码来解决问题了。请看一个经典案例: https://samsaffron.com/archive/2011/10/28/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 的倍数的等待时间”不?请跳传送门: http://blogs.microsoft.co.il/sasha/2009/07/31/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 的行为。看,调优参数列表之一: https://docs.microsoft.com/en-us/dotnet/framework/configure-apps/file-schema/runtime/?redirectedfrom=MSDN 不过 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 实现起来也稍微复杂一些。 |
39
yagao0o 2020-12-15 15:52:16 +08:00
举个稍微有点偏的例子:
你开车,每次都加满油,轮胎买来是啥就是啥,也就这么开下去了。(同时你想换胎和加多少油你其实每次也可以自己决定,车出厂已经调整到针对大部分情况下最佳的状态了) 人家开 F1,根据不同的场景,要换不同的胎,油也是看情况加多少。 当然.NET 和 Java 没这么大差距, |
41
whileFalse 2020-12-15 15:59:36 +08:00 2
我同意 LZ 的观点。
我是一个运维。在测试环境中,我用一台机器跑几十个 Java 微服务。于是我有一个很简单的需求:让这些服务和平共处,不要干爆内存或 CPU 。我希望简简单单地将单个微服务限制为使用 1G 内存。至于这些内存怎么分配,是你 JVM 自己的问题。 然而 JVM 做不到。我要让 JVM 不超过 1G 内存,那我得把 Xmx 设置为 512m,然后一小撮 VM 逼近 1G 内存,大部分 VM 跑 700M 。这些配置必须小心调教,不然有的服务就会疯狂 GC,干爆 CPU 。如果不小心把限制设的太宽,VM 们还会干爆内存,导致部分 VM 崩溃然后不停重新启动,于是服务器就挂了。 |
42
cheng6563 2020-12-15 16:05:23 +08:00
设计思路问题吧,为了提高性能,JVM 的思路是拿了就不还,那么码农就要考虑到底给你多少。
|
43
FreeEx 2020-12-15 16:05:51 +08:00
@MinQ 互联网行业不能这样玩的,停服更新在外界看来就是实力不足的表现,如果是需要线上打断点调试代码,这...肯定是不被允许的。
|
45
zsl199512101234 2020-12-15 16:09:45 +08:00
说实话,学 java 的都很能说,分布式事务,高可用常常挂在嘴边的
|
46
FreeEx 2020-12-15 16:09:51 +08:00
@whileFalse .NET 连给你限制内存的机会都不给。。。你这个场景更需要使用 VM 或者 docker 来隔离
|
47
zsl199512101234 2020-12-15 16:09:58 +08:00
不然不好找工作
|
48
FreeEx 2020-12-15 16:11:46 +08:00
@zsl199512101234 说实话,分布式事务能不用就别用,高可用这个没得黑,都得做。
|
49
whileFalse 2020-12-15 16:12:26 +08:00
@FreeEx #46 我是用 Docker 隔离的。然而参数调不好的话他自己总是炸呀。一个服务老重启很烦呀。
|
50
Suclogger 2020-12-15 16:24:28 +08:00 1
选了 java,只能一条路走到黑了。建议学 rust
|
51
mosliu 2020-12-15 16:38:29 +08:00
个人感觉,普通跑个 java 服务,基本不用太考虑调优问题,设定个-Xmx 就足够了,除非代码稀烂,内存泄漏等等的,那些当我没说
一般用到 jvm 调优的,大都是大数据,分布式的东西,非常吃内存的,经常有 GC 的。 通过调优,可能本来一台服务器 能跑 4 个实例的,内存就有些争用的,跑到 6 个了 或者原本 gc 到了 s 级的下降回 ms 级。 调优不是比烂,而是让好的更好。 深入到 GC 层去理解系统怎么执行的,是一个通过调优去理解 JVM,然后最终反馈到之后的代码编写方式的事情。 |
52
wanguorui123 2020-12-15 16:40:08 +08:00
我想对 NET 调优,可是 GC 模块不开放那么多参数给我调试
|
53
micean 2020-12-15 16:42:12 +08:00
|
54
zsl199512101234 2020-12-15 16:47:32 +08:00
@FreeEx 分布式事务是最恶心的了,要注意哪些地方得加锁,不加锁会很麻烦
|
55
nightwitch 2020-12-15 16:55:55 +08:00 8
简单的逻辑推论
1.Net Core 团队官方表示 CLR 任何时候都是最优性能状态 2..Net Core 团队提供了大量的选项用于在运行期调整 GC 的设置,以帮助程序员提高 App 的峰值性能( https://docs.microsoft.com/en-us/dotnet/core/run-time-config/garbage-collector)。 如果 1 成立,2 是行为艺术么? |
56
RipL 2020-12-15 17:12:51 +08:00
楼上那些 说 开发基本上用不到 jvm 调优的 不知道咋想的,不知道是项目 low 流量小,还是自己根本就不去深究一个问题的根源。
|
57
RipL 2020-12-15 17:14:50 +08:00
@zsl199512101234 分布式事务和高可用 都能被黑 。。。。。。
|
58
leonardyang 2020-12-15 17:20:28 +08:00
@FreeEx 虽然这么做确实一般不合规,但是从实现而言 java 也能啊,不就是 remote debug 吗
|
59
FreeEx 2020-12-15 17:22:46 +08:00
@whileFalse 你应该是没有限制 docker 的 cpu 和内存吧?如果你们是使用 springcloud 那一套的话,限制了 docker,Java 程序就不再需要限制了。
|
60
coderwl 2020-12-15 17:22:55 +08:00
Java 作为使用最多的业务开发语言,大部分的云服务上都跑着 Java 的服务,这时候 JVM 吃内存的弊端就显现出来了,各个大厂都有对 JVM 做魔改,针对自己的业务特点来做优化,节省成本,Oracle 也知道这点,搞了个 GraalVM,把 Java 编译为 native 执行
|
61
charlie21 2020-12-15 17:24:00 +08:00 1
@nightwitch 不是哦,这是让你可以瞎调,然后把性能降低
|
62
real3cho 2020-12-15 17:24:30 +08:00 1
.Net Core 团队官方表示 CLR 任何时候都是最优性能状态 消息源?
个人愚见 官方不会说这种很满的话 |
63
hantsy 2020-12-15 17:30:09 +08:00
JVM 虚拟机调优要看具体使用的 VM 是什么,对照设置,各种实现很多参数可能不通用,版本也重要。
很讨厌这些面试 JVM 调优的题目,大部分也是网上剽切的内容,面试很多也拿出来装 B 而已。比如上面的 PermSize 之类,OpenJDK11 早就没用了。 |
64
putaozhenhaochi 2020-12-15 17:38:11 +08:00
楼主没学深 不要出来装逼。
V2 众 教你做人 |
65
enihcam OP @nightwitch 从来不知道怎样更改 CoreCLR 选项可以比默认值获得更高的 GC 性能。要不你来秀一下?
|
66
lewis89 2020-12-15 18:14:51 +08:00 2
因为要面八股文啊,各位写 CRUD 的兄弟们 扪心自问,Controller -> Service -> DAO 一杆子捅到底的老哥,
你写的业务代码除了几个 bean 的生命周期长一点外,有几个运行时的对象能活到老年代? |
67
susuper 2020-12-15 18:17:59 +08:00
我上次面试官跟我说这些可能对我这个学习阶段效果体现出来的不大,我这个水平其实用不到太多调优,但是学 jvm 一类,其实是培养的自己的思维,让自己在写到这些大内存相关代码,能有意识的去控制代码优劣程度
|
68
chihiro2014 2020-12-15 18:18:52 +08:00
一般来说,JVM 不需要调优= =
|
69
lewis89 2020-12-15 18:19:32 +08:00
而且现在基本上是分布式锁,不会在线程之间共享变量,连虚拟机逃逸分析之类的东西都不用关心
|
70
whileFalse 2020-12-15 18:30:11 +08:00
@FreeEx 所以 SpringCloud 能自动获取容器对 CPU 和内存的限制是么?我用的 k8s 。
|
71
taogen 2020-12-15 18:31:22 +08:00 via Android
因为不操心所以是码农 🐶
|
72
CharlotteLi 2020-12-15 18:33:59 +08:00
又到了我最爱的环节
|
73
whileFalse 2020-12-15 18:38:58 +08:00
|
74
INCerry 2020-12-15 18:39:57 +08:00 1
@FreeEx 哈哈 这个我不同意
bing.com 全球第二大搜索引擎 使用.net5.0 构建 https://cn.bing.com/version stackoverflow.com 全球第一大程序员问答社区 使用.net5.0 构建 cnblogs.com 第一大中文博客站点 使用.net5.0 构建 |
75
Ehco1996 2020-12-15 18:41:52 +08:00
因为人多,所以要区分
|
76
kkeiko 2020-12-15 18:56:17 +08:00
因为 Java 落后于 .Net 满意了吗
|
77
nicebird 2020-12-15 19:03:49 +08:00
抽象泄露,到一定级别都会遇到这种问题,不管是什么语言。
|
78
netnr 2020-12-15 19:09:11 +08:00 via Android
前面遇到日志组件内存泄露,先耗完内存再耗 swap 再被 linux 杀掉
而同样部署到 win 一点问题没有,不知道是平台区别还是 win 买单了 |
79
sagaxu 2020-12-15 19:14:04 +08:00 via Android
老八股了,比如 java7 和 java8 的 hashmap 实现区别,就算你入门从 11 开始,也要学习历史知识应试。
|
81
lewis89 2020-12-15 23:32:24 +08:00
@EminemW #80 那是框架引用了你的对象,Controller -> Service -> DAO 其实你业务代码栈空间这块其实已经没有引用了,讲道理实际上大部分只在栈空间上存在引用的对象是活不到老年代的。
|
82
gadsavesme 2020-12-16 00:03:50 +08:00
也没有几个人人在一直 jvm 调优啊,但你 jvm 原理相关的东西肯定还是要看啊,出了 oom 之类的问题总归要会分析问题吧。不知道为啥好多 v2 上的人对很多底层实现都嗤之以鼻,好像就是一辈子 crud 不会遇到问题一样。
|
83
iyangyuan 2020-12-16 08:25:48 +08:00
我觉得更像是 jvm 给用户提供了一种优化的方式和空间,假如 jvm 没有这种功能,就需要用户提高编码水平,不然 jvm 运行效率可能不高,总之就是一个平衡,不用也行,用了更好。
|
84
Cloutain 2020-12-16 08:49:26 +08:00 1
代码上乱写 乱搞,怎么调也没用啊
|
86
a728976009 2020-12-16 09:56:33 +08:00
@whileFalse java10 的更新向下迁移至 Java8 了,详见 http://seanthefish.com/2020/11/11/jvm-in-container/
|
88
LMuyi 2020-12-16 10:25:14 +08:00
引战贴
|
89
ShotaconXD 2020-12-16 10:31:07 +08:00
@LMuyi #88 引战贴+1
感觉问这个没意义 |
90
Suddoo 2020-12-16 12:05:23 +08:00
@lewis89 其实就是为了面试,JDK 最新的 GC 其实已经没那么多参数可调了,或者说调优这个事情 JDK 已经帮你做得差不多了,还在看 JVM 调优就是为了面试
|
91
hehe12980 2020-12-16 14:02:37 +08:00 1
JVM 调优 就是配一堆参数么 真的有几个人懂 JVM 调优 连周志明那本书 讲的都是很表明的东西 还有怎么证明你配的参数是最优? 其实 就是面试风气导致的,有哪几位大神,真正做过 JVM 调优的,@我,我开开眼
|