当前位置: 首页 > news >正文

优质做网站哪家正规网业游戏大全

优质做网站哪家正规,网业游戏大全,网上商城建设方案,中核集团电子商城map在内存中总是会增长#xff1b;它不会收缩。因此#xff0c;如果map导致了一些内存问题#xff0c;你可以尝试不同的选项#xff0c;比如强制 Go 重新创建map或使用指针。 在 Go 中使用map时#xff0c;我们需要了解map增长和收缩的一些重要特性。让我们深入探讨这一点…map在内存中总是会增长它不会收缩。因此如果map导致了一些内存问题你可以尝试不同的选项比如强制 Go 重新创建map或使用指针。 在 Go 中使用map时我们需要了解map增长和收缩的一些重要特性。让我们深入探讨这一点以防止可能导致内存泄漏的问题。 首先为了查看这个问题的一个具体例子让我们设计一个场景在这个场景中我们将使用以下map m : make(map[int][128]byte)每个 m 的值都是一个包含 128 字节的数组。我们将执行以下操作 分配一个空的map。添加 100 万个元素。删除所有元素并运行垃圾回收GC。 在每个步骤之后我们希望打印堆的大小使用一个 printAlloc 实用函数。这将展示这个示例在内存方面的行为方式 func main() {n : 1_000_000m : make(map[int][128]byte)printAlloc()for i : 0; i n; i { // Adds 1 million elementsm[i] [128]byte{}}printAlloc()for i : 0; i n; i { // Deletes 1 million elementsdelete(m, i)}runtime.GC() // Triggers a manual GCprintAlloc()runtime.KeepAlive(m) // Keeps a reference to m so that the map isn’t collected }func printAlloc() {var m runtime.MemStatsruntime.ReadMemStats(m)fmt.Printf(%d KB\n, m.Alloc/1024) }我们分配一个空的map添加 100 万个元素删除 100 万个元素然后运行垃圾回收。我们还确保使用 runtime.KeepAlive 保持对map的引用以防止map被收集。让我们运行这个示例 0 MB -- After m is allocated 461 MB -- After we add 1 million elements 293 MB -- After we remove 1 million elements我们观察到了什么起初堆大小很小。然后在将 100 万个元素添加到map后它显著增长了。但是如果我们期望在删除所有元素后堆大小会减小这并不是 Go 中map的工作方式。最后尽管 GC 已经收集了所有元素但堆大小仍然是 293 MB。因此内存缩小了但并非我们可能预期的方式。这其中的原理是什么我们需要深入了解一下 Go 中map的工作原理。 map提供了一个无序的键值对集合其中所有的键都是唯一的。在 Go 中map基于哈希表数据结构一个数组其中每个元素都是指向键值对存储桶的指针如图1所示。 图1 — 哈希表示例重点关注存储桶 0。 每个存储桶都是一个固定大小的数组包含八个元素。如果要将元素插入已经满了的存储桶即存储桶溢出Go 会创建另一个包含八个元素的存储桶并将前一个存储桶链接到它上。图2显示了一个例子 图2 — 如果存储桶溢出Go 会分配一个新的存储桶并将前一个存储桶链接到它上。 在底层Go 中的map是指向 runtime.hmap 结构体的指针。该结构体包含多个字段其中包括一个 B 字段表示map中存储桶的数量 type hmap struct {B uint8 // log_2 of # of buckets// (can hold up to loadFactor * 2^B items)// ... }在添加了100万个元素之后B 的值等于18这意味着有 2¹⁸ 262,144 个存储桶。当我们删除了100万个元素后B 的值是多少呢仍然是18。因此map仍然包含相同数量的存储桶。 原因在于map中存储桶的数量是不可缩减的。因此从map中删除元素不会影响现有存储桶的数量它只是将存储桶中的槽清零。map只能增长并拥有更多的存储桶它永远不会缩小。 在先前的示例中我们从461 MB减少到了293 MB因为元素被收集但运行垃圾回收并没有影响map本身。即使额外存储桶的数量因为溢出而创建的存储桶也保持不变。 让我们退一步讨论map无法缩小的情况何时可能成为问题。想象一下使用 map[int][128]byte 来构建缓存。这个map以每个客户IDint为键保存一个长度为128字节的序列。现在假设我们想保存最近的1000位客户。map的大小将保持不变所以我们不必担心map无法缩小的问题。 但是假设我们想要存储一小时的数据。同时我们的公司决定在黑色星期五进行大促销在一个小时内我们可能会有数百万的客户连接到我们的系统。但是在黑色星期五之后的几天我们的map将包含与高峰期相同数量的存储桶。这就解释了为什么在这种情况下我们可能会遇到内存消耗高却不会显著减少的情况。 如果我们不想手动重启服务来清理map消耗的内存量有哪些解决方案一种解决方案可以是定期重新创建当前map的副本。例如每小时我们可以构建一个新map复制所有元素并释放先前的map。这种选择的主要缺点是在复制后直到下一次垃圾回收之前我们可能会在短时间内消耗两倍于当前内存。 另一种解决方案是将map类型更改为存储数组指针map[int]*[128]byte。这并没有解决我们会有大量存储桶的问题然而每个存储桶条目将为值保留指针的大小而不是128字节64位系统上为8字节32位系统上为4字节。 回到原始场景让我们比较每种map类型在每个步骤后的内存消耗。以下表格显示了比较。 Stepmap[int][128]bytemap[int]*[128]byte分配一个空的 map0 MB0 MB添加100万个元素461 MB182 MB删除所有元素并运行GC293 MB38 MB 正如我们所看到的在删除所有元素后使用 map[int]*[128]byte 类型所需的内存量明显较少。此外在这种情况下由于一些优化措施以减少内存消耗高峰时期所需的内存量也较少显著。 注意如果键或值超过128字节Go 将不会直接将其存储在map存储桶中。相反Go 将存储用于引用键或值的指针。 结论 正如我们所见向map添加 n 个元素然后删除所有元素意味着在内存中保持相同数量的存储桶。因此我们必须记住由于 Go map只能增长因此其内存消耗也会随之增加。它没有自动化的策略来缩小。如果这导致内存消耗过高我们可以尝试不同的选项比如强制 Go 重新创建map或使用指针来检查是否可以进行优化。
http://www.w-s-a.com/news/840497/

相关文章:

  • 做网站店铺图片用什么软件网络营销方案格式
  • 做外贸要自己建网站吗有效的网络营销方式
  • 精通网站开发书籍做网站获取手机号码
  • 论坛做视频网站有哪些济南新站seo外包
  • 哪类型网站容易做冷水滩做微网站
  • 搭建企业网站流程保定徐水网站建设
  • 建设单位到江川区住房和城乡建设局网站伦敦 wordpress 设计
  • 响应式网站的服务麦德龙网站建设目标
  • 做国外单的网站叫什么海南省海口市网站建设
  • 杭州响应式网站案例wordpress5.2.2
  • 网站建设运营维护合同wordpress资源搜索插件
  • 国外网站流量查询东莞网站建设教程
  • 餐饮类网站建设达到的作用东莞工程建设交易中心网
  • 网站设计 知识产权湖北网站建设xiduyun
  • 猫咪网站模版下载中国风 古典 红色 网站源代码
  • 个人网站备案模板制作网站首页
  • 潍坊正规建设网站网站建设设计作业
  • 推荐一下网站谢谢辽宁住房城乡建设部官方网站
  • 网站文件大小英选 网站开发
  • 济南建网站哪家好wordpress编辑器排行
  • 在福州做搬家网站多少钱画册设计网站有哪些
  • 如何让别人浏览我做的网站哪些方法可以建设网站
  • 网站建设与管理网络推广的优点
  • 美食网站的设计与制作做网站的电销话术
  • 中国档案网站建设现状研究陕西建设厅执业资格注册中心网站
  • 网站建设的内容管理怎么用ps切片在dw里做网站
  • 建设婚恋网站用什么搭建涿州网站开发
  • 做知识内容的网站与app哈尔滨哪里有做网站的
  • 青岛企业网站建站模板百度网站建设推广
  • 做360网站中保存的图片存在哪里个人建立网站要多少钱