kneo

kneo

V2EX 第 640670 号会员,加入于 2023-07-28 00:00:58 +08:00
今日活跃度排名 3862
根据 kneo 的设置,主题列表被隐藏
二手交易 相关的信息,包括已关闭的交易,不会被隐藏
kneo 最近回复了
旧版本堆增长之后就是不缩小的。你可以升级到最新的 jdk 试试。
8 小时 14 分钟前
回复了 Liuour 创建的主题 程序员 各位程序员,你们日常「中文与英文间添加空格」吗
一般不加。不过像 v2 好像会自动帮你加。
10 小时 43 分钟前
回复了 carljson 创建的主题 游戏开发 分享我一年多的做独立游戏开发经验心得
独立游戏上 taptap 不要版号吗?
1 天前
回复了 hez2010 创建的主题 程序员 运行 100 万个异步并发任务需要多少内存
@bli22ard

> 就启动 goroutine ,不管是堆还是栈,没搞懂它有什么存

启动 goroutine ,实际上是你用 goroutine 加载了一个函数。栈就是这个函数的运行环境。哪怕是一个空函数,只要没被优化掉,也是一个函数调用,也必须有栈。

类似的,你在其它语言里启动一个线程也需要提供一个可运行函数(或者等价物)。这不是 GO 专有的概念。

> 如果是参数,变量,为什么要是 2kb ,而不是这些参数、变量的实际大小

栈的特点就是动态增长。因为函数调用需要把子函数的存储也分配到这个栈上。函数的嵌套越多,需要的内存就越多。

栈空间不够用就需要重新分配内存并且把旧的栈数据复制过去。(这里指的是虚拟线程,原生线程收到操作系统限制可能无法修改栈大小。)

如果初始化栈过小,频繁的扩容会影响性能。

初始栈过大,会造成内存浪费。

2KB 是一个性能权衡的结果。

您可能需要找一些函数调用和栈内存的示意图看一下。不一定非是 GO 的。
1 天前
回复了 hez2010 创建的主题 程序员 运行 100 万个异步并发任务需要多少内存
@bli22ard

> 更本质的是,为什么需要这个 2kb 内存,这 2kb 存的什么东西,这个期待有实力的人研究一下 runtime 。

2KB 就是栈啊……和其他语言没有本质区别。函数的参数,变量,闭包之类的。不过正常情况 Java 在栈上存对象只存指针,Go 因为有 struct ,相比 Java ,栈内存的使用频率会更多点,预分配的大一点也是合理的。
1 天前
回复了 xzg1993 创建的主题 问与答 外观好看的 windows 本,有哪些推荐。
@sean419 明白。这机器不错的。如果有别的颜色更好。
1 天前
回复了 xzg1993 创建的主题 问与答 外观好看的 windows 本,有哪些推荐。
@sean419 谢谢朋友,英雄联盟能跑到多少帧啊?我买了之后因为不能联网,测试了几个小游戏,像魔法工艺第一层 BOSS 才几十个弹幕就卡了,黎明前 20 分玩了几分钟也是明显卡。有个不吃显卡的 Noita 倒是很流畅。我感觉 CPU 确实不错,但是稍微用到 GPU 的可能就要拉胯了……我想了想就退了。
2 天前
回复了 hez2010 创建的主题 程序员 运行 100 万个异步并发任务需要多少内存
@bli22ard

> 比较好奇,每个 goroutine 2kb ,到底存的是什么
> 最后 @lesismal @kneo 两位高手来围观

见笑了,谈不上高手。

我的理解这 2KB 就是预分配的栈大小。过小的初始栈可能会导致频繁的内存重新分配。
2KB 可能是 go 团队在性能测试之后得到的一个比较好的默认值。这个值也是经过多次调整的:

https://stackoverflow.com/questions/22326765/go-memory-consumption-with-many-goroutines

> in Go 1.4: the minimum size of the goroutine stack has decreased from 8Kb to 2Kb.
> https://github.com/golang/go/blob/bbd25d26c0a86660fb3968137f16e74837b7a9c6/src/runtime/stack.go#L72:
_StackMin = 2048


也许可以把 2KB 改成 1KB 重新编译一个 go 版本,内存测试的结果就和 Java 一样了。当然前提是 1KB 对这个测试来说够用,够不够用我也不知道……

当然真实环境大家确实不在意一个 goroutine 占用了 2KB 是不是太多。但是这个测试至少让我们知道了这个 2KB 的存在。程序员总是对这种小细节感兴趣的。
2 天前
回复了 hez2010 创建的主题 程序员 运行 100 万个异步并发任务需要多少内存
@CloveAndCurrant 哈哈,给你机会了。既然你不会我就帮你个忙。

Wiki 中很明确的提到了 stackful 和 stackless:

https://en.wikipedia.org/wiki/Coroutine#Definition_and_types

> Besides that, a coroutine implementation has 3 features:
> - ...
> - ...
> - whether a coroutine is able to suspend its execution from within nested function calls. Such a coroutine is a stackful coroutine. One to the contrary is called stackless coroutines, where unless marked as coroutine, a regular function can't use the keyword yield.

同时也举例了:

https://en.wikipedia.org/wiki/Coroutine#Lua

> Lua has supported first-class stackful asymmetric coroutines since version 5.0 (2003), in the standard library coroutine.

很明显,有栈协程和无栈协程都是协程,不是加个定语就可以随便用的。Wiki 也不是连个有栈无栈都不懂的“过时”信息。

同一页面也明确指出了:

https://en.wikipedia.org/wiki/Coroutine#Go

> However, goroutines are not coroutines (for instance, local data does not persist between successive calls).

goroutines 不是协程,加再多定语也没用。

这个总结不是给 @CloveAndCurrant 这种人看的,他除了嘴硬啥也不懂。但我相信其他人看了自然能明辨是非。

我不相信 @CloveAndCurrant 能再给出任何有意义的回复了。不和他聊了。
关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3182 人在线   最高记录 6679   ·     Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 · 10ms · UTC 12:47 · PVG 20:47 · LAX 04:47 · JFK 07:47
Developed with CodeLauncher
♥ Do have faith in what you're doing.