我正在开发与私有(private)以太坊区 block 链网络交互的 REST 服务。首先,我将 Java 与 Web3j 库和 Jersey 结合使用。一切都按预期工作,但服务的单个实例(不是 geth 客户端)占用了高达 500MB 的 RAM!因为我需要同时运行多个实例(~40)以进行模拟,我想要更轻便的东西。
因此我切换到 Go(32 位版本,Windows 10)和原始的 go-ethereum 包。然而,当我调用并存储 bind.NewTransactor() 的结果时,我很惊讶地发现程序的内存消耗上升到 ~250MB ,它返回一个 *TransactOpts。我查看了资料来源,但无法解释这种行为。
这是正常的吗(如果是,为什么?)还是我遗漏了什么?
这是我的代码:
import (
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"strings"
)
const WALLET_PATH string = "path/to/json/wallet"
func main() {
data, _ := ioutil.ReadFile(WALLET_PATH)
// up to this point, the program only takes a few MBs of RAM
auth, _ := bind.NewTransactor(strings.NewReader(string(data)), "mypassphrase")
// and here the allocated memory rises up to ~270MB
_ = auth
}
最佳答案
好吧,我真的没有找到我的问题的答案,但我确实找到了解决方法,所以无论如何我都会分享它。
正如@MichaelHampton 所建议的,我内存了我的程序。 top 10 命令揭示了以下内容:
(pprof) top 10
Showing nodes accounting for 256MB, 99.88% of 256.30MB total
Dropped 15 nodes (cum <= 1.28MB)
flat flat% sum% cum cum%
256MB 99.88% 99.88% 256MB 99.88% github.com/ethereum/go-ethereum/vendor/golang.org/x/crypto/scrypt.Key
0 0% 99.88% 256MB 99.88% github.com/ethereum/go-ethereum/accounts/abi/bind.NewTransactor
0 0% 99.88% 256MB 99.88% github.com/ethereum/go-ethereum/accounts/keystore.DecryptKey
0 0% 99.88% 256MB 99.88% github.com/ethereum/go-ethereum/accounts/keystore.decryptKeyV3
0 0% 99.88% 256MB 99.88% github.com/ethereum/go-ethereum/accounts/keystore.getKDFKey
0 0% 99.88% 256.01MB 99.88% main.main
0 0% 99.88% 256.30MB 100% runtime.main
可以看到,内存消耗来自scrypt包中的Key函数,它被bind.NewTransactor(...)间接调用。来自文档:
Key derives a key from the password, salt, and cost parameters, returning a byte slice of length keyLen that can be used as cryptographic key.
特别是,这对应于如何从 JSON 钱包文件生成私钥。实际上,该函数本身会为密码计算分配大量内存。但我不明白的是为什么这个巨大的内存分配似乎在 key 生成后持续存在(当我用 log.Fatal(http.ListenAndServe( ":8080", nil)) 紧随其后)。
为了证实我的怀疑,我使用了另一种方法来生成我的*TransactOpts,它包括直接从其十六进制表示中获取 key ,而不是从钱包文件中生成它:
func main() {
privateKey, err := crypto.HexToECDSA("myKeyInHex")
if err != nil {
log.Fatal(err)
}
auth := bind.NewKeyedTransactor(privateKey)
_ = auth
}
虽然 bind.NewTransactor 和 bind.NewKeyedTransactor 返回完全相同的对象(唯一的区别是 key 是如何生成的),使用 bind.NewTransactor 导致 256MB 持久 内存分配,而不是为 bind.NewKeyedTransactor 分配几 KB,如下所示:
(pprof) top 10
Showing nodes accounting for 11.04kB, 100% of 11.04kB total
Showing top 10 nodes out of 19
flat flat% sum% cum cum%
6.83kB 61.90% 61.90% 6.83kB 61.90% time.initLocalFromTZI
4.21kB 38.10% 100% 4.21kB 38.10% github.com/ethereum/go-ethereum/crypto/sha3.(*state).clone (inline)
0 0% 100% 4.21kB 38.10% github.com/ethereum/go-ethereum/accounts/abi/bind.NewKeyedTransactor
0 0% 100% 4.21kB 38.10% github.com/ethereum/go-ethereum/crypto.Keccak256
0 0% 100% 4.21kB 38.10% github.com/ethereum/go-ethereum/crypto.PubkeyToAddress
0 0% 100% 4.21kB 38.10% github.com/ethereum/go-ethereum/crypto/sha3.(*state).Sum
0 0% 100% 6.83kB 61.90% github.com/pkg/profile.Start
0 0% 100% 6.83kB 61.90% github.com/pkg/profile.Start.func2
0 0% 100% 6.83kB 61.90% log.(*Logger).Output
0 0% 100% 6.83kB 61.90% log.(*Logger).formatHeader
因此,对于我的模拟,我将从我的 JSON 钱包生成我的私钥并将它们存储在上游的文本文件中,然后使用 bind.NewKeyedTransactor(...)。我知道这无论如何都不安全,但为了我的模拟目的,这就足够了。
但是,我很确定 bind.NewTransactor 没有关于内存消耗的预期行为,所以我要打开一个 issue on the go-ethereum repository .
关于go - go-ethereum `bind.NewTransactor()` 的巨大持久内存分配?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51791869/
作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代
通过rubykoans.com,我在about_array_assignment.rb中遇到了这两段代码你怎么知道第一个是非并行赋值,第二个是一个变量的并行赋值?在我看来,除了命名差异之外,代码几乎完全相同。4deftest_non_parallel_assignment5names=["John","Smith"]6assert_equal["John","Smith"],names7end45deftest_parallel_assignment_with_one_variable46first_name,=["John","Smith"]47assert_equal'John
它不等于主线程的binding,这个toplevel作用域是什么?此作用域与主线程中的binding有何不同?>ruby-e'putsTOPLEVEL_BINDING===binding'false 最佳答案 事实是,TOPLEVEL_BINDING始终引用Binding的预定义全局实例,而Kernel#binding创建的新实例>Binding每次封装当前执行上下文。在顶层,它们都包含相同的绑定(bind),但它们不是同一个对象,您无法使用==或===测试它们的绑定(bind)相等性。putsTOPLEVEL_BINDINGput
对于Rails模型,是否可以/建议让一个类的成员不持久保存到数据库中?我想将用户最后选择的类型存储在session变量中。由于我无法从我的模型中设置session变量,我想将值存储在一个“虚拟”类成员中,该成员只是将值传递回Controller。你能有这样的类(class)成员吗? 最佳答案 将非持久属性添加到Rails模型就像任何其他Ruby类一样:classUser扩展解释:在Ruby中,所有实例变量都是私有(private)的,不需要在赋值前定义。attr_accessor创建一个setter和getter方法:classUs
ruby如何管理内存。例如:如果我们在执行过程中采用C程序,则以下是内存模型。类似于这个ruby如何处理内存。C:__________________|||stack|||------------------||||------------------|||||Heap|||||__________________|||data|__________________|text|__________________Ruby:? 最佳答案 Ruby中没有“内存”这样的东西。Class#allocate分配一个对象并返回该对象。这就是程序
我早就知道Ruby中的“常量”(即大写的变量名)不是真正常量。与其他编程语言一样,对对象的引用是唯一存储在变量/常量中的东西。(侧边栏:Ruby确实具有“卡住”引用对象不被修改的功能,据我所知,许多其他语言都没有提供这种功能。)所以这是我的问题:当您将一个值重新分配给常量时,您会收到如下警告:>>FOO='bar'=>"bar">>FOO='baz'(irb):2:warning:alreadyinitializedconstantFOO=>"baz"有没有办法强制Ruby抛出异常而不是打印警告?很难弄清楚为什么有时会发生重新分配。 最佳答案
我正在尝试在Rails上安装ruby,到目前为止一切都已安装,但是当我尝试使用rakedb:create创建数据库时,我收到一个奇怪的错误:dyld:lazysymbolbindingfailed:Symbolnotfound:_mysql_get_client_infoReferencedfrom:/Library/Ruby/Gems/1.8/gems/mysql2-0.3.11/lib/mysql2/mysql2.bundleExpectedin:flatnamespacedyld:Symbolnotfound:_mysql_get_client_infoReferencedf
假设您在Ruby中执行此操作:ar=[1,2]x,y=ar然后,x==1和y==2。是否有一种方法可以在我自己的类中定义,从而产生相同的效果?例如rb=AllYourCode.newx,y=rb到目前为止,对于这样的赋值,我所能做的就是使x==rb和y=nil。Python有这样一个特性:>>>classFoo:...def__iter__(self):...returniter([1,2])...>>>x,y=Foo()>>>x1>>>y2 最佳答案 是的。定义#to_ary。这将使您的对象被视为要分配的数组。irb>o=Obje
你好,我无法成功如何在散列中删除key后释放内存。当我从哈希中删除键时,内存不会释放,也不会在手动调用GC.start后释放。当从Hash中删除键并且这些对象在某处泄漏时,这是预期的行为还是GC不释放内存?如何在Ruby中删除Hash中的键并在内存中取消分配它?例子:irb(main):001:0>`ps-orss=-p#{Process.pid}`.to_i=>4748irb(main):002:0>a={}=>{}irb(main):003:0>1000000.times{|i|a[i]="test#{i}"}=>1000000irb(main):004:0>`ps-orss=-p
我正在使用Dragonfly在Rails3.1应用程序上处理图像。我正在努力通过url将图像分配给模型。我有一个很好的表格:{:multipart=>true}do|f|%>RemovePicture?Dragonfly的文档指出:Dragonfly提供了一个直接从url分配的访问器:@album.cover_image_url='http://some.url/file.jpg'但是当我在控制台中尝试时:=>#ruby-1.9.2-p290>picture.image_url="http://i.imgur.com/QQiMz.jpg"=>"http://i.imgur.com/QQ