类似于 java heap(-Xmx1024m)的设置,各种语言都是怎样设置的?
比较想知道 .net go swift rust node php haskell 等等
1
timpaik 2022-06-02 10:12:48 +08:00 via Android
Rust: 你创建多少变量 /结构体就占用多少内存,变量出了作用域立马释放就不占内存了,没有虚拟机,也不存在 GC ,更没有内存上限的问题
|
2
pengtdyd 2022-06-02 10:21:13 +08:00 3
C : 内存上限?老子说什么是上限什么就是上限!
|
3
andyhuzhill 2022-06-02 10:30:49 +08:00
C C++的内存上限只和操作系统和硬件有关吧
|
4
westoy 2022-06-02 10:36:45 +08:00 2
cgroups 大法好
|
5
kkocdko 2022-06-02 10:37:16 +08:00 via Android 4
楼上几位能不能看清题再答。题主是“主观需要上限功能”而不是“被上限所困扰”。
远古时代可以用 ulimit ,现在主要是在内存分配器上动手脚,比如可以 hook 一下 malloc 啥的。 |
6
agagega 2022-06-02 10:38:36 +08:00 via iPhone
如果 Java 里面已占用内存超过这个最大值但是又不能 GC 怎么办?
|
7
CodeCodeStudy 2022-06-02 10:43:52 +08:00
PHP 如果是 FPM 的话,脚本执行完毕就释放全部内存了。可以在 php.ini 中设置 memory_limit ,如果不限制,将 memory_limit 设置为-1 ,也可以在代码里使用 ini_set('memory_limit', '1G') 来设置
|
8
qwq11 2022-06-02 10:46:03 +08:00 via Android
据我所知,好像这些语言写的 90%的东西都不需要限制内存,简单搜了下 CLR 好像没有限制内存的选项,剩下 10%可能就是上 cgroups 了吧
|
9
Building 2022-06-02 10:48:40 +08:00 4
语言没有办法控制内存上限,就好像加法不能限制最大数一样,能限制内存上限的是 runtime
|
10
yazinnnn OP 就是说非 vm 语言都需要在系统中控制吗?
像 dart 这种就可以通过虚拟机控制? 假如说用 rust 或者 go 开发了一个 web 服务,想控制他的内存上限在 200m,只能用系统限制,二进制文件是无法限制的 这样? clr 也不能限制么? |
12
laowudxf 2022-06-02 11:09:56 +08:00
Swift 貌似没有参数可以控制内存上限,本来就是指针引用计数来控制内存,该用多少就用多少。我的 Swift 后台服务长时间在 32m 以内。
|
13
SMGdcAt4kPPQ 2022-06-02 11:10:29 +08:00 via Android
CLR 可以限制内存
docs.microsoft .com/en-us/dotnet/core/runtime-config/garbage-collector#heap-limit |
14
arischow 2022-06-02 11:11:37 +08:00
丢进 Docker 然后 limit ?
或者使用本身 Docker 所利用的 cgroups ? |
15
DOLLOR 2022-06-02 11:21:06 +08:00
node 的 [--max-old-space-size=] 应该能起到类似功能,比如
node --max-old-space-size=5120 app.js # Increase limit to 5GB |
16
cheng6563 2022-06-02 11:25:06 +08:00 1
@agagega 会在分配内存的时候(如 new XXX)弹出 OOM 异常。
这里有个巨坑,A 线程分配占用大内存并保持不动,然后可能会 B 线程分配新内存弹出 OOM 异常,然后 B 线程捕获异常打日志,然后打日志的代码也 OOM ,最后整个线程挂掉并且日志文件没日志。完全失去控制。 生产环境一般会加-XX:+ExitOnOutOfMemoryError 使其 OOM 就直接干掉整个进程直接重启完事。 |
17
jiangwei2222 2022-06-02 11:27:32 +08:00
@kkocdko #5 比起 hook malloc 啥的,直接启一个 docker ,然后限制 docker 容器的内存更合适一点吧。自己 hook 稍不注意就出问题了
|
18
LeegoYih 2022-06-02 11:30:55 +08:00
语言层面本身没法限制吧,如果要实现的话可以用虚拟机或者容器,不过如果 OOM 会被 KILL 。
|
19
hbdh5 2022-06-02 11:39:35 +08:00
@Building 其实如果一定要从语言层面限制也是可以的,比如 rust 或 c++可以自己实现一个超过指定内存就 panic 的内存分配器然后指定为全局内存分配器
|
20
northernlights0 2022-06-02 11:45:34 +08:00
有虚拟机的语言在虚拟机层面控制,其它的在操作系统层面
|
21
BeautifulSoap 2022-06-02 11:49:34 +08:00 via Android
内存上限是系统(或虚拟机)控制的不是语言自身
|
22
nothingistrue 2022-06-02 12:22:27 +08:00
JVM 的内存上限是由 VM 而不是又运行程序控制的,严格的说它也是由操作系统(只不过是个 VM )而非应用控制的。另外,JVM 能精确控制的只有堆内存,整个 VM 的内存(即 java.exe 进程占用的内存),它也是不精确控制的。
|
23
FrankHB 2022-06-02 12:36:45 +08:00
@Building 你好歹讲点别的吧,加法?明显语言的语义上不限制上限的麻烦得多以至于几乎没什么语言不限制。只要你用的数据类型明确限制了最大元素,加法还能绕出去?就是任意精度数值,内部表示也受到空间的限制而不可能表示任意大的数;真正没限制最大数的怕就是只有 lazy list 之类的模拟了,你倒是统计下有几个语言这么做了?
最简单的,C 无符号数直接钦定不溢出,内部表示占用固定大小。只要语言残废到都是类似的玩意儿再在超出实例时禁止翻译就能静态证明不可超出限制了。阉掉了动态分配和递归的 C 类似物也是这样,只不过不方便算出具体上限是多少,一般要凑。 |
24
yolee599 2022-06-02 12:46:30 +08:00 via Android
C:可以自己实现 malloc ,给你多少就只能用多少
|
25
dalabenba 2022-06-02 12:55:01 +08:00 via Android
应用->内存分配库->系统调用
从内存分配库的角度看,需要分配库追踪分配的数量,才能做到控制内存上限 从操作系统角度看,ulimit 可以限制分配虚拟地址的大小,实际物理的占用可能要 cgroup 来做 不管是什么语言,最终都会调到这两个来,vm 类的语言可能在内存分配库之上还有自己的限制(比如你说的 jvm) |
26
yazinnnn OP graalvm 利用 native-image 构建的二进制文件依然可以用-Xmx 来设置程序运行时的堆内存大小
那么就表示这个二进制文件仍然包含了一层 jvm,由 jvm 来管理实际程序? |
27
yazinnnn OP 搜了一下看到 go 有 SetMaxHeap 函数来对堆内存进行设置,这是自带 gc 的语言的标准库实现
https://www.jianshu.com/p/4069d1e3d716 https://groups.google.com/g/golang-codereviews/c/brkajcJ0mhI/m/VyXYtel4BgAJ 那么 rust 有没有类似功能呢? |
28
learningman 2022-06-02 13:57:10 +08:00
rust 不带 gc ,运行的时候二进制里面只有你的代码。
你不写一个那就是没有 |
29
Building 2022-06-02 14:04:09 +08:00 via iPhone
@FrankHB 你先搞清楚什么是语言,什么是数据类型吧。如果 Int 的最大值为 255 是因为一个 Int 只用了 8 个字节,和语言没关系,就好像你定义了 a[10],语言也不会限制你写 a[100],只是这样写会报错,同理你想访问 a[10^100000],一点问题都没有,语言不会也不应该考虑去帮你考虑内存够不够的问题
|
30
timpaik 2022-06-02 16:41:40 +08:00 via Android
@yazinnnn #27 jvm 回收的内存也是程序不用的内存,jvm 大部分情况是定时检测有没有可以回收的内存,而 Rust 不需要 GC 就可以释放这些内存,一旦程序不用就会立即释放。你既然创建了变量申请了内存,又不想让它申请内存,为什么会有这种需求呢
|
31
haoliang 2022-06-02 20:10:17 +08:00
python 可以使用 resources.setrlimit (为啥大家都不提这个 setrlimit ,不会是我审错题了吧?)
|
32
haoliang 2022-06-02 20:13:47 +08:00
当然它实际就是 ulimit ,不过在语言中我们总要对应到方法吧...
|
34
2NUT 2022-06-02 22:56:51 +08:00
不带 gc 的语言 在编译期就确定了 内存占用了
|
36
zeni123 2022-06-03 05:51:28 +08:00
人工控制内存使用上限
|
37
FrankHB 2022-06-03 06:47:04 +08:00
|
38
Building 2022-06-03 09:41:24 +08:00 via iPhone
@FrankHB 报错是编译器行为……你不想报错完全可以强行编译,和语言没有关系。计算机理论里内存是无限的就好像数学世界里数是无限的一样。无论用什么语言,本质上都只是再控制指针操作内存,这是计算机的基本原理,如果语言能限制内存使用,就好像说数学坐标轴最大值只能到 1024 一样
|
39
FrankHB 2022-06-03 09:50:44 +08:00
@Building ?我甚至还要在这科普什么叫 conformance 和数学常识了吗?
该报错的不报错,不该报错的报错了,那叫 bug ,不管是编译器还是运行时的。决定什么该报错,该报什么错的是 spec 里的规则。写编译器一般没什么能力同时做整个 spec ,所以直接用的语言的 spec ;就算自己写 spec ,不是照抄的,实际上就发明了语言出来。 内存无限和数学如何明显是你 yy 。都玩那种玩具 model ,那早搞体系结构的就破产了。数学不好请自己补课。数无限?抽象代数我实在不想教,要不你还是先搞清楚比如 C 的无符号数折腾的就是数学上的 modular arithmetic 那套这样的入门经验再说吧。 |
40
bugu1986 2022-06-03 10:36:18 +08:00
有的语言没有 gc 不需要设置
|
41
Building 2022-06-03 13:43:28 +08:00
@FrankHB 你扯的什么乱七八糟的东西啊,来来来,最简单的,写一段程序,只要输入一个字符,立刻申请 1gb 的内存放着,别管我用来干什么,你举个例子,哪一门语言的编译器这么牛逼不给过?
|
43
hxndg 2022-06-04 01:02:44 +08:00
@FrankHB
不好意思,刚才不小心敲错了。。。。 实际上我没太看明白你的意思,可以详细解释下吗?或者指明一些资料?我内存这块的很多认识都是原先从实际工程现看的,可能已经和现在的发展脱节了? 原先做性能优化,使用 linux 的 hugepage 直接在用户态内存管理的时候就是类似 slab 来做操作,这个控制是算 runtime 做的吗? C 应该不限制这个?另外目前 x64 虚拟内虽然保存了一些高位,但是基本可以认为是无限的? |
46
461da73c 2022-06-05 14:50:56 +08:00
JAVA 真是又慢又费内存。
|
48
FrankHB 2022-06-23 19:21:04 +08:00
@Building 所以你也太小看编译器的下限了。
“申请内存”?你是不是不知道直接不提供给你“申请内存”的实现也符合 ISO C ?你先给我说说你怎么确保一个 strictly conforming 的 C 程序“申请内存”还一定能过? 顺便,让 int main(){int a;}直接给 stack overflow 都是符合 ISO C 的。你说你见到过的编译器都会过?行,我写个程序判断源代码是不是长这样,如果是就直接给你生成一跑就会挂掉的二进制代码,不是就扔给 gcc ,不也是个符合 ISO C 的实现?(不符直接扔标准条款谢谢。) (顺便,int a;不算“申请”内存。) 所以用得着你个“申请内存”个什么寄玩意儿啊…… @hxndg 上面举例子过了,用到个自动对象都可以给你当作栈爆了,也是合乎规矩的。即便没什么实现那么不要脸。 实际上这是 ISO C 比较下限,事实上允许实现随便钦定资源限制,但一点都没说最小限制是什么,只说超过限制 UB 。 而且这个比“分配内存”特殊在于原则上是没法直接加规则修的,因为 ISO C 抽象机里根本就没调用栈这种东西,自动对象不是被“分配”的。(但显然又要占资源,否则不确保不会爆栈的现有实现都不符合 ISO C 了。) ISO C++同理( core lang 里唯一一个提到 stack 的是 stack unwinding )。 其实这种设计就没什么可移植性。 /proc/pid/limit 这个倒是比较有实际意义的好例子。不过,这个显示不出语言设计不讲理的地方。 |
49
Building 2022-06-23 20:55:06 +08:00 via iPhone
@FrankHB 为什么你总是不肯正面回答问题?扯这么多乱七八糟的东西?你就回答具体那一门语言的编译器动态申请内存不让过就行了
|
50
FrankHB 2022-06-23 22:01:13 +08:00
@Building 我没正面回答么?是不是你看不懂什么叫 ISO C ?
退一步讲,你连 OP 都不是,我 at 你又不是私信,非得专门喂给你看的所以一定要浅显到连你都看得懂? 再退一步讲,为什么我有义务回答你经常连 well-formed 都算不上的问题? 而且你哪来的自信定义什么叫“乱七八糟”,你是很确信在这个问题领域比我更权威咯? |
51
Building 2022-06-23 22:09:29 +08:00
@FrankHB 所以呢?快回答啊,哪一门语言不给过?哪一门?说出来啊?承认自己错真的不丢脸,但是你气急败坏的样子真的很搞笑
|