业务中有这样一个struct:

  1. type bizData struct{
  2. A uint64
  3. B uint64
  4. C int32
  5. D uint32
  6. }

虽然没有实测,但我猜测这样的对齐方式,这个struct占24字节。

业务中用一个map指向这些对象: map[uint64]*bizData

这样的存储对象,一个容器开启10GB内存,最多存储60万左右的对象,容器内存就爆了。

于是自己实现一个简易的内存池:mempool.go

  1. package mempool
  2. //实现一个按块扩展的内存池
  3. type memPool struct {
  4. datas [][]bizData
  5. freeNode chan uint32
  6. countOfBlock int
  7. }
  8. //NewMemPool 构造内存池对象
  9. func NewMemPool(countOfBlock int) *memPool {
  10. out := &memPool{
  11. datas: [][]bizData{make([]bizData, countOfBlock)},
  12. freeNode: make(chan uint32, countOfBlock),
  13. countOfBlock: countOfBlock,
  14. }
  15. for i := 0; i < countOfBlock; i++ {
  16. out.freeNode <- uint32(i)
  17. }
  18. return out
  19. }
  20. func (pool *memPool) moreBlock() {
  21. pool.datas = append(pool.datas, make([]bizData, pool.countOfBlock))
  22. ch := make(chan uint32, len(pool.datas)*pool.countOfBlock)
  23. close(pool.freeNode)
  24. for item := range pool.freeNode {
  25. ch <- item
  26. }
  27. start := (len(pool.datas) - 1) * pool.countOfBlock
  28. for i := 0; i < pool.countOfBlock; i++ {
  29. ch <- uint32(start + i)
  30. }
  31. pool.freeNode = ch
  32. }
  33. func (pool *memPool) Get() uint32 {
  34. if len(pool.freeNode) == 0 {
  35. pool.moreBlock()
  36. }
  37. select {
  38. case idx := <-pool.freeNode:
  39. return idx
  40. default:
  41. panic("impossible")
  42. }
  43. }
  44. func (pool *memPool) Put(idx uint32) {
  45. pool.freeNode <- idx
  46. }
  47. func (pool *memPool) Item(idx uint32) *bizData {
  48. blockIdx := int(idx) / pool.countOfBlock
  49. loc := int(idx) % pool.countOfBlock
  50. return &(pool.datas[blockIdx][loc])
  51. }

然后把对象的引用方式修改为: map[uint64]uint32 //值映射数据块的下标

使用上面的内存池后,分配250万小对象,进程内存始终未超过600mb!!

so, 大量小对象的情况下,自己实现内存池更好!

【笔记】对golang的大量小对象的管理真的是无语了……的更多相关文章

  1. 读书笔记 effective c++ Item 13 用对象来管理资源

    1.不要手动释放从函数返回的堆资源 假设你正在处理一个模拟Investment的程序库,不同的Investmetn类型从Investment基类继承而来, class Investment { ... ...

  2. golang学习笔记14 golang substring 截取字符串

    golang学习笔记14 golang substring 截取字符串golang 没有java那样的substring函数,但支持直接根据 index 截取字符串mystr := "hel ...

  3. golang学习笔记13 Golang 类型转换整理 go语言string、int、int64、float64、complex 互相转换

    golang学习笔记13 Golang 类型转换整理 go语言string.int.int64.float64.complex 互相转换 #string到intint,err:=strconv.Ato ...

  4. golang学习笔记11 golang要用jetbrain的golang这个IDE工具开发才好

    golang学习笔记11   golang要用jetbrain的golang这个IDE工具开发才好  jetbrain家的全套ide都很好用,一定要dark背景风格才装B   从File-->s ...

  5. Java小对象的解决之道——对象池(Object Pool)的设计与应用

    一.概述 面向对象编程是软件开发中的一项利器,现已经成为大多数编程人员的编程思路.很多高级计算机语言也对这种编程模式提供了很好的支持,例如C++.Object Pascal.Java等.曾经有大量的软 ...

  6. java并发编程笔记(四)——安全发布对象

    java并发编程笔记(四)--安全发布对象 发布对象 使一个对象能够被当前范围之外的代码所使用 对象逸出 一种错误的发布.当一个对象还没构造完成时,就使它被其他线程所见 不安全的发布对象 某一个类的构 ...

  7. [Effective Java 读书笔记] 第二章 创建和销毁对象 第五条

    第五条 避免创建不必要的对象 书中一开始举例: String s = new String("stringette"); // don't do this //应该使用下面,只会创 ...

  8. C#开发微信门户及应用(23)-微信小店商品管理接口的封装和测试

    在上篇<C#开发微信门户及应用(22)-微信小店的开发和使用>里面介绍了一些微信小店的基础知识,以及对应的对象模型,本篇继续微信小店的主题,介绍其中API接口的封装和测试使用.微信小店的相 ...

  9. (笔记)Linux内核学习(九)之内核内存管理方式

    一 页 内核把物理页作为内存管理的基本单位:内存管理单元(MMU)把虚拟地址转换为物理 地址,通常以页为单位进行处理.MMU以页大小为单位来管理系统中的也表. 32位系统:页大小4KB 64位系统:页 ...

随机推荐

  1. THUSC 2021 游记

    想了想不往博客园放不行,还是放上来了. 原文 \[\texttt{Brief Introduction} \] 众所周知,THUSC2021 5 月 15-16 日在杭州市 XJ 中学举办,然而由于 ...

  2. Do PDB Files Affect Performance?

    After a detour into Historical Debugging, it's time to come back to return to answering questions ab ...

  3. C# Dispose模式

    需要明确一下C#程序(或者说.NET)中的资源.简单的说来,C#中的每一个类型都代表一种资源,而资源又分为两类: 托管资源:由CLR管理分配和释放的资源,即由CLR里new出来的对象: 非托管资源:不 ...

  4. 交通运输类文档下载——JT/T 808-2019、JT/T 809-2019文档分享

    JT/T 808-2019.JT/T 809-2019文档分享 网盘:https://pan.baidu.com/s/1vfgenani8WR3in2lua3qWQ提取码:fktd 官网下载808协议 ...

  5. Spring Tool Suite(STS)基本安装配置

    下载jar包:https://spring.io/tools 下载完成后 打开所在文件夹 执行命令行 jar -jar  下载的jar包文件名 然后会自动解压 双击打开软件 配置主面板窗口 配置好之后 ...

  6. Nacos配置中心+ASP.NET Core

    Nacos配置中心 nacos 是一个构建云原生应用的动态服务发现.配置管理和服务管理平台.. 源码已上传至 github 配置管理 asp.net core中所有的配置项,如appsetting.j ...

  7. 【linux】环境变量生命周期的操作方式

    目录 前言 1. 修改环境变量 1.1 手动指定 1.2 临时生效 1.3 永久生效 链接 前言 参考: 李柱明博客 本文主要记录 linux 环境变量配置的生命周期. 如,修改环境变量 PATH 是 ...

  8. C# RabbitMQ的使用

    本文目的如题. 安装 先说一下RabbitMQ的安装,建议使用Docker镜像安装,Docker安装的好处是不管Windows系统还是Linux,安装步骤少,安装方法相同,不容易出错.使用下面的命令就 ...

  9. 【Java笔记】applet和html注意

    1.首先记得extends Applet 泪目 2.如果不分包,HTML可以写 <applet code="HelloWorldApplet.class" width=150 ...

  10. 制作登录页面,点击键盘的 Enter 键或者单击“登录”按钮,验证用户输入的邮箱和密码是否正确

    查看本章节 查看作业目录 需求说明: 制作登录页面 点击键盘的 Enter 键或者单击"登录"按钮,验证用户输入的邮箱和密码是否正确 实现思路: 准备登录的静态页面 在页面中嵌入脚 ...