EOS 数据库RAM使用量的计算
如果你是EOS的合约开发者,相信你很有可能跟我一样对内存(RAM)的使用量感到不解。在使用multi_index
进行数据存储时,明明只存了一点数据,但区块链浏览器中显示的内存占用量却上升了不少。在这篇文章中,我们就来对内存用量一探究竟,精确计算出存储数据所需要的RAM。我们会首先编写一个简单的合约,用以向multi_index
内存入数据。部署合约后,每次调用接口前后都查询一下RAM用量,并予以记录。
合约编写
新建合约目录:
1 2 3 | $ mkdir addrow $ cd addrow $ touch addrow.cpp |
这里是一份简单的合约,用户每次调用add
时,数据库中都会多存一行记录
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | #include < eosiolib /eosio.hpp> class [[eosio::contract]] addrow : public eosio::contract { public: addrow( eosio::name receiver, eosio::name code, eosio::datastream< const char*> ds ) : eosio::contract(receiver, code, ds), _students(receiver, code.value) {} //添加学生 [[eosio::action]] void add(eosio::name user) { require_auth(user); eosio::print("Add student ", user); _students.emplace(get_self(), [&](auto& p) { p.id = _students.available_primary_key(); }); } struct [[eosio::table]] students { uint64_t id; // primary key uint64_t primary_key() const { return id; } }; //数据表根据age排序 typedef eosio::multi_index<"students"_n, students > studentstable; //students数据库表 studentstable _students; }; EOSIO_DISPATCH( addrow, (add) ) |
使用eosiocpp
工具进行编译后,得到addrow.wasm
与addrow.abi
文件:
1 2 | $ eosiocpp -o addrow.wast addrow.cpp $ eosiocpp -g addrow.abi addrow.cpp |
部署合约
1 2 3 | cleos -u https://jungle2.cryptolions.io:443 set contract zmcheng12345 /root/github.com/addrow -p zmcheng12345@active 查账户内存使用情况: cleos -u https://jungle2.cryptolions.io:443 get account zmcheng12345 -j |
我查询到的数值为:
1 | "ram_usage": 52665 |
这个数值可能根据你的编译工具和参数不同而有所变化。我们以查询到的数值为基础,进行后续的差值计算。
调用合约,新增一行数据:
1 | $ cleos push action eosio.ramfee add '' -p eosio.ramfee |
查询用量,得到的结果是:
1 | "ram_usage": 52897 |
再新增一行并查询,这次的结果是:
1 | "ram_usage": 53017 |
通过计算可以得出,新增第一行的内存占用量达到了232字节!而第二行的占用量也高达120字节!如果继续新增行数,你会发现后续的行占用量均为120字节。
也就是说,存储一个仅有一个uint64_t
字段(大小为8字节)的数据表,首行占用232字节,后续行数占用120字节。
总结
在EOS合约内使用multi_index
存储数据(不使用secondary index的情况下),需要承担以下RAM使用量:
- 首先,每新增一行记录,都会占用112字节+实际数据大小
- 如果这个数据表本身不存在,需要再额外收取112字节的RAM占用
可以看到,每行数据的overhead(112字节)还是相当大的。如果单纯地使用数据结构大小来计算,预期使用量与实际使用量的误差会非常大(本例中,首次存储8字节数据的实际用量是数据大小的29倍!)。而得知了精确的占用量算法之后,就可以更好地规划dApp所需要的内存量了。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 张高兴的大模型开发实战:(一)使用 Selenium 进行网页爬虫
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
2014-09-18 POJ1426:Find The Multiple(算是bfs水题吧,投机取巧过的)
2014-09-18 POJ:3083 Children of the Candy Corn(bfs+dfs)