go主题免费下载魔幻明珠哪儿有下???

共0条评论,0人参与,
10-1409-2709-1804-1303-1212-0411-3011-1911-1911-16后使用我的收藏没有帐号?
所属分类: &
查看: 1749|回复: 0
天涯明月刀曲无忆寻找密语中的明珠在哪 明珠虽好任务
天涯明月刀曲无忆寻找密语中的明珠在哪 明珠虽好任务明珠怎么找
正版休闲足球手游 完美继承经典作品!
抢先体验分享截图 赢千元京东卡好礼!golang 经验交流, 如何避免 gc 杀手
10:40:22 +08:00 · 6577 次点击
golang 的 gc 从实践来看弱爆了,
while { readline, }
处理大文本很快内存消耗完,
大量 cpu 时间消耗到 gc 上。
下面两个工具可以缓解这种问题,
一是一块 buffer 上用多个 slice 连续存储,
另一个是自动缩放的一块 buffer 存变长的值。
type BytesPool struct {
Buffer []byte
//size, initial pool size
func NewBytesPool(size int) *BytesPool {
return &BytesPool{make([]byte, size), 0, 0}
//get slice
func (b *BytesPool) AllocSlice(size int) []byte {
//expand 1.5x
if len(b.Buffer) & size + b.Index {
nb := make([]byte, int(float64(len(b.Buffer)) * 1.5) + size)
b.Buffer = nb
slice := b.Buffer[b.Index:b.Index+size]
b.Top = b.Index
b.Index += size
return slice
func (b *BytesPool) GetSlice() []byte {
return b.Buffer[b.Top:b.Index]
type AutoResizeByteArray struct {
Buffer []byte
func NewAutoResizeByteArray(size int) *AutoResizeByteArray {
return &AutoResizeByteArray{make([]byte, size), 0}
func (b *AutoResizeByteArray) AllocSlice(size int) []byte {
if len(b.Buffer) & size {
nb := make([]byte, int(float64(len(b.Buffer)) * 1.5) + size)
b.Buffer = nb
b.Top = size
return b.Buffer[:size]
func (b *AutoResizeByteArray) GetSlice() []byte {
return b.Buffer[:b.Top]
func testBytesPool() {
b := NewBytesPool(3)
copy(b.AllocSlice(4), []byte(&abcd&))
fmt.Printf(&%s\n&, b.GetSlice())
copy(b.AllocSlice(2), []byte(&ef&))
fmt.Printf(&%s\n&, b.GetSlice())
b1 := NewAutoResizeByteArray(3)
copy(b1.AllocSlice(4), []byte(&abcd&))
fmt.Printf(&%s\n&, b1.GetSlice())
大家还有什么好注意? 欢迎交流。
第 1 条附言 &·&
22:39:29 +08:00
发贴目标不是要跟你们喷的, 拒不参与语言圣战, 就此终止。
34 回复 &| &直到
10:04:17 +08:00
& & 11:40:30 +08:00
golang 标准库 1.4 起自带内存池
& & 12:10:04 +08:00
你为什么不用 bytes.Buffer 要自己写呢?标准库里面的
不是 golang 的 gc 弱爆了,是你对 golang 的了解弱爆了
& & 12:23:56 +08:00
sync.Pool
bytes.Buffer
&- chan []byte (LeakyBuffer)
官方都快有 3 种标准写法了, LZ 你弱爆了
& & 12:39:57 +08:00
看了楼上的回复我感觉自己弱爆了。。。
& & 12:42:01 +08:00
@ 补个连接
第三个写法 cloudflare 出了个改进版。
& & 13:13:44 +08:00
& & 13:16:52 +08:00
golang 是个大坑啊,比 shell 还难写
& & 13:22:45 +08:00
这两都不是一类
说难写的看看 Erlang CommonLisp
& & 14:47:16 +08:00
嗯,是实践,而不是最佳实践~
& & 14:59:28 +08:00
@ lisp 大部分时候写起来还是蛮舒服的,除了设计宏的时候
& & 15:37:57 +08:00
erlang 啃了一段时间,最后实在习惯不了那种思路,放弃。
& & 17:26:40 +08:00
我其实是想讨论下怎么把内存释放掉,
内存池只是避免通过 gc 的方案
c 里有 malloc ,
free 成对,
成对使用就可以保持内存消耗相对较小
golang 里就不一样,
一路 malloc,
什么时候 free 是不确定事件,
最后内存使用越来越大, 不可控制。
& & 17:29:40 +08:00
@ 关键你本来就不该频繁 malloc free 啊,就算你 c ,这么频繁 malloc free ,增加内存碎片,影响性能,最终还是要靠内存池来解决。
& & 17:35:34 +08:00
@ 如果你非得坚持错误的做法,那你可以手工 gc , runtime.GC(),不推荐!不推荐!不推荐!
& & 17:50:52 +08:00
性能不是关键问题,
随着 objects 越来越多, 进程内存越占越多,
gc 的回收效果不好才是个大麻烦。
& & 17:58:07 +08:00
while {readline} 不建内存池这种模式下,
10 亿行文本,
吃内存嗖嗖的,
慢点是没有关系的.
& & 19:18:36 +08:00
-- while {readline} 不建内存池这种模式下, 10 亿行文本, 吃内存嗖嗖的, 慢点是没有关系的.
我并不理解你这个需求,如果你能提供更多代码就更好了。因为在 while 里面,最终只是复用一个 slice 而已(当然在超过当前长度的时候会申请新的内存空间), GC 应该是可控的。
// 使用 *bufio.Reader ReadLine
上面提到的几种方案, sync.Pool , bytes.Buffer ,有什么理由不能用吗?
& & 21:41:02 +08:00
本来 GC 就是为了减轻心智负担的,非得自己整,不是作死是啥,还怪语言?
觉得不“可控”,你去写 C 好了,多进程下检测泄露、死锁?
连 cache tmpfile 都不会用,还 10 亿行文本,呵呵。
& & 21:42:04 +08:00
和小学生解释这么多干嘛。。。
& & 22:17:55 +08:00
& & 10:58:57 +08:00
@ 参考我上面提问,我是想知道这个问题是什么,如果你能提供示例代码就更好了。
& & 11:56:47 +08:00
while { readline,
每次都分配内存而且不归我管的函数},
我讲的是 gc 对这种情况反应不行,
也就是下面的情况做不到.
enter function
malloc
-& new
自动 free -& delete
leave function
```
```go
package main
func main() {
b := make([][]byte, 3000000)
for i := 0; i & 3000000; i++ {
buffer := make([]byte, 1024)
copy(buffer, []byte(&abcd&))
b[i] = buffer
}
}
```
```shell
gc1(1): 1+0+33224+1 us, 0 -& 68 MB, 21 (21-0) objects, 2 goroutines, 16/0/0 sweeps, 0(0) handoff, 0(0) steal, 0/0/0 yields
gc2(1): 0+2+29460+1 us, 68 -& 68 MB, 22 (23-1) objects, 3 goroutines, 16/0/2 sweeps, 0(0) handoff, 0(0) steal, 0/0/0 yields
gc3(1): 0+8+29552+0 us, 68 -& 137 MB, ) objects, 3 goroutines,
sweeps, 0(0) handoff, 0(0) steal, 0/0/0 yields
gc4(1): 0+881+29664+1 us, 136 -& 136 MB, 6-69794) objects, 3 goroutines, 3 sweeps, 0(0) handoff, 0(0) steal, 0/0/0 yields
gc5(1): 0+10+30403+0 us, 136 -& 273 MB, ) objects, 3 goroutines,
sweeps, 0(0) handoff, 0(0) steal, 0/0/0 yields
gc6(1): 0++0 us, 272 -& 272 MB, ) objects, 3 goroutines, 50 sweeps, 0(0) handoff, 0(0) steal, 0/0/0 yields
gc7(1): 0+15+31651+0 us, 272 -& 545 MB, ) objects, 3 goroutines,
sweeps, 0(0) handoff, 0(0) steal, 0/0/0 yields
gc8(1): 0++0 us, 543 -& 543 MB, ) objects, 3 goroutines, 11 sweeps, 0(0) handoff, 0(0) steal, 0/0/0 yields
gc9(1): 0+23+33831+0 us, 543 -& 1086 MB, ) objects, 3 goroutines, /0 sweeps, 0(0) handoff, 0(0) steal, 0/0/0 yields
gc10(1): 0++0 us, 1082 -& 1082 MB, 6) objects, 3 goroutines, /130262 sweeps, 0(0) handoff, 0(0) steal, 0/0/0 yields
gc11(1): 1+39+39331+1 us, 1082 -& 2164 MB, 0) objects, 3 goroutines, /0 sweeps, 0(0) handoff, 0(0) steal, 0/0/0 yields
gc12(1): 0++0 us, 2155 -& 2155 MB, 4) objects, 3 goroutines, /268228 sweeps, 0(0) handoff, 0(0) steal, 0/0/0 yields
```
& & 12:07:31 +08:00
@ 除了做一些底层的 dirty hack,
针对各种 golang 的内置对象,
你有什么办法用 golang 的 api 接口实现这个吗?
```golang
enter function
malloc -& new
自动 free -& delete
leave function
```
& & 12:28:50 +08:00
package main
func main() {
b := make([][]byte, 3000000)
for i := 0; i & 3000000; i++ {
buffer := make([]byte, 1024)
copy(buffer, []byte(&abcd&))
b[i] = buffer
你这个例子来说几乎是无解的,因为无论如何变量会被引用到,所以 GC 本身不会回收的,哪怕使用 sync.Pool ,这种情况下和 GC 关系不大,哪怕你使用 Java ,一样遇到这个问题。
** 所以你的问题是,如何能够更加“紧凑”的使用内存,避免内存碎片。**
按照你的这个例子,那么就是大量的循环里面创造 slice ,但是 slice 很大,而实际存储内容比较小。
“看起来内存很浪费”
解决方法来看:
1 如果使用自己开发的内存池,在大量动态变化情况下,实际上,你就是在实现一个小型的 GC 了。并且不会比使用 sync.Pool 好多少的。
2 借鉴 memcache 的解决方法,申请大的内存块,然后按照长度切片,比如 128b, 256b, 512b, 1k, 2k ,然后根据实际数据做一些 copy 工作。
3 sync.Pool 和 按照长度分片的 buffer 结合起来,基本能实现你的需求了。
节省内存和避免 COPY 是一个矛盾的问题,内存越紧凑,当长度变化时,需要申请新的空间, COPY 数据,反之就是内存越浪费,这是一个权衡的问题。
& & 12:37:08 +08:00
如果能实现下面这种模式, 问题也是可以解决的,
while {malloc,
这样内存耗用就相对较小,
不会 malloc 堆在一起又占内存而且一下 gc 造成巨大的延迟。
```gol
enter function
malloc -& new
自动 free -& delete
leave function
```
& & 12:38:34 +08:00
什么叫 dirty....自己去操心资源的分配和释放这些事情就很 dirty
什么叫 hack...
比如 c 语言经常这么写:
void f(int *multiret1, int *multiret1);
// 多值返回
void f(struct T* bufFromCallerStack); // 在调用者的栈空间中分配
struct T {
struct ListN
// 从 node 的指针“反射”取出 T 对象
}
------不熟习 c 的人说,这叫 hack--------
------熟习 c 的人说,这是常识啊-----
对象池,复用缓存空间,这些对于熟习 Go 的人说是常识,不是 hack
& & 12:44:39 +08:00
C 语言指针可以乱跑就没 hack 这回事,
我讲的是 go 里要实现如下模式, 需要 hack
enter function
malloc -& new
自动 free -& delete
leave function
& & 12:50:25 +08:00
又没人阻止你这么做
func f(reuse []byte) {
enter function
use reuse object ,不要 malloc
不需要 free
leave function
}
& & 12:55:59 +08:00
问题是 f 多数情况下不是自己写的,
所以要求 gc 能自己搞定这个事。
& & 14:14:49 +08:00
可能我比较 low ,申请资源的既然能进行 free -& delete ,那么为什么就不能复用?
& & 23:02:34 +08:00
唉,我在 5# 贴得链接无人问津,明珠暗投啊。
& & 05:37:49 +08:00
@ 题外话:
struct T {
struct ListN // 从 node 的指针“反射”取出 T 对象
这是什么情况用?
& & 09:04:39 +08:00
Go 根本没有 delete 这个功能,如何 delete ?
或者说本来就是 gc 在自动 delete
在任何语言里,频繁地 new 和 delete 都不好,只不过用 Go 这么做显得更不好。
在任何语言里,都应该用一个池
所以,上面早就有人说过了, “官方都快有 3 种标准写法了”...
& & 10:04:17 +08:00
@ 我讲如果能处理
enter function
new slice
leave function
问题就小很多
在 while 里引用了别人写的这种函数就是 for {malloc},
给 gc 集中式回收造成了很大的压力
如果能实现把 function 内显而易见的 heap 分配可以立刻回收掉,
这种问题就能解决掉,
内存占用不会升的太快,
gc 造成的延迟也会减小。
这事不在内存池上,
因为有了 gc , 别人的代码会&不负责任的&这么干.
& · & 575 人在线 & 最高记录 3541 & · &
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.1 · 28ms · UTC 21:37 · PVG 05:37 · LAX 14:37 · JFK 17:37? Do have faith in what you're doing.好像明珠台有个节目是讲装修比赛的!反正是跟室内设计有关的,有谁知道是什么节目啊_百度知道
好像明珠台有个节目是讲装修比赛的!反正是跟室内设计有关的,有谁知道是什么节目啊
我有更好的答案
是《欢乐GO-快乐装修房 我为你分单》这个节目有讲西湖明珠频道《升级空间》这个栏目
你大概给我讲一下是什么时间段播放的先啊,现在还有放么?是晚上八点半左右的么?
西湖明珠频道21点吧
为您推荐:
其他类似问题
明珠台的相关知识
换一换
回答问题,赢新手礼包
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。}

我要回帖

更多关于 go锁屏主题下载 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信