Rust 如何通过多个Java线程使用只读数据?

Rust 如何通过多个Java线程使用只读数据?,rust,java-native-interface,borrowing,Rust,Java Native Interface,Borrowing,我有一个结构Foo和FooRef,它引用了Foo中的数据: struct Foo{/*…*/} 结构FooRef(&'a self)->FooRef{ $env.get_字段(*$class,“ptr”,“J”) .ok() .然后(|j | j.j().ok()) .然后| ptr |{ 如果ptr==0{ 没有一个 }否则{ 部分(ptr为*mut Foo) } }) }; } 宏规则!foo_ref_mut_ptr{ ($env:expr,$class:expr)=>{ $env.get_

我有一个结构
Foo
FooRef
,它引用了
Foo
中的数据:

struct Foo{/*…*/}
结构FooRef(&'a self)->FooRef{
$env.get_字段(*$class,“ptr”,“J”)
.ok()
.然后(|j | j.j().ok())
.然后| ptr |{
如果ptr==0{
没有一个
}否则{
部分(ptr为*mut Foo)
}
})
};
}
宏规则!foo_ref_mut_ptr{
($env:expr,$class:expr)=>{
$env.get_字段(*$class,“ptrRef”,“J”)
.ok()
.然后(|j | j.j().ok())
.然后| ptr |{
如果ptr==0{
没有一个
}否则{
部分(ptr为*mut FooRef)
}
})
};
}
宏规则!富穆特{
($env:expr,$class:expr)=>{
foo|u mut|ptr!($env,$class).map(| ptr |&mut*ptr)
};
}
宏规则!富欧参考{
($env:expr,$class:expr)=>{
foo|u ref|mut|ptr!($env,$class).map(| ptr |和*ptr)
};
}
#[允许(非蛇形情况)]
#[没有损坏]
发布不安全的外部“系统”fn Java\u test\u App\u create(\u env:JNIEnv,\u class:JClass)->jlong{
Box::into_raw(Box::new(Foo::default())作为jlong
}
#[允许(非蛇形情况)]
#[没有损坏]
发布不安全的外部“系统”fn Java_test_App_createRef(env:JNIEnv,class:JClass)->jlong{
让foo=foo_mut!(env,class).expect(“对未初始化的数据调用了createRef”);
让foo_ref=foo.create_ref();
方框::输入原始(方框::新(foo_ref))作为jlong
}
#[允许(非蛇形情况)]
#[没有损坏]
发布不安全外部“系统”fn Java_test_App_reload(env:JNIEnv,class:JClass){
让foo=foo_mut!(env,class).expect(“foo必须初始化”);
*foo=foo{
数据:vec![“hello”.to_owned();1024*1024],
};
}
#[允许(非蛇形情况)]
#[没有损坏]
发布不安全外部“系统”fn Java_test_App_destroy(env:JNIEnv,class:JClass){
放下武器(武器参考武器)(环境,职业));
放下武器(武器装备)(环境,职业));
}
#[允许(非蛇形情况)]
#[没有损坏]
发布不安全外部“系统”fn Java_test_App_destroyRef(env:JNIEnv,class:JClass){
放下武器(武器参考武器)(环境,职业));
}
不安全fn下降ptr(ptr:选项){
如果让一些(ptr)=ptr{
让_foo=Box::from_raw(ptr);
//福落在这里
}
}
#[衍生(默认)]
结构Foo{
资料来源:Vec,
}
#[衍生(默认)]

struct FooRef我认为是内存泄漏的问题实际上不是内存泄漏。问题是分配器正在使用线程本地竞技场。因此,无论哪个线程重新加载250MB的数据,都会保留分配的空间,而不会将其返回给系统。这个问题不是JNI特有的,但也发生在纯粹的安全防锈代码中。看

在我的例子中,默认创建的竞技场数量默认为8*cpu计数=64。可以通过设置
MALLOC\u ARENA\u MAX
env变量来覆盖此设置

因此,我通过将
MALLOC\u ARENA\u MAX
env变量设置为1解决了这个问题。所以,我采取的方法很好。这只是平台特定的问题


这个问题只发生在WSL的Ubuntu中。我也在Windows 10上尝试了相同的代码,没有任何调整,它可以完美地工作,没有任何问题。

我认为内存泄漏的问题实际上不是内存泄漏。问题是分配器正在使用线程本地竞技场。因此,无论哪个线程重新加载250MB的数据,都会保留分配的空间,而不会将其返回给系统。这个问题不是JNI特有的,但也发生在纯粹的安全防锈代码中。看

在我的例子中,默认创建的竞技场数量默认为8*cpu计数=64。可以通过设置
MALLOC\u ARENA\u MAX
env变量来覆盖此设置

因此,我通过将
MALLOC\u ARENA\u MAX
env变量设置为1解决了这个问题。所以,我采取的方法很好。这只是平台特定的问题


这个问题只发生在WSL的Ubuntu中。我也在Windows 10上尝试了相同的代码,没有任何改动,它可以完美地工作,没有任何问题。

评论不用于扩展讨论;此对话已结束。评论不用于扩展讨论;这段对话已经结束。