为什么在持有Mutex时多个线程使用过多的内存

古尔温德·辛格

下面的代码在单线程中使用〜150MB,但在100个线程中使用几个GB:

use std::sync::{Arc, Mutex};
use std::thread;

fn main() {
    let f = Arc::new(Mutex::new(Foo::new("hello")));

    let mut threads = vec![];
    for i in 0..100 {
        let f = f.clone();
        let t = thread::spawn(move || loop {
            let mut locked = f.lock().unwrap();
            *locked = Foo::new("hello");
            drop(locked);
            println!("{} reloaded", i);
            thread::yield_now();
        });
        threads.push(t);
    }

    threads.into_iter().for_each(|h| h.join().unwrap());
}

pub struct Foo {
    _data: Vec<String>,
}

impl Foo {
    fn new(s: &str) -> Foo {
        Foo {
            _data: vec![s.to_owned(); 1024 * 1024],
        }
    }
}

按住时LockGuard,线程应具有独占访问权。因此,此时Foo应分配值,而应丢弃旧值。因此,对我来说,从多个线程中调用这么多的内存正在使用,这没有任何意义。

谁能解释为什么此代码使用了这么多的内存?

Java中的类似代码即使有1000个线程也可以将内存保持在200mb左右。

import java.util.ArrayList;
import java.util.List;

public class Foo {
    private List<String> data;

    public static void main(String[] args) {
        Foo f = new Foo();
        for (int i = 0; i < 1000; i++) {
            int n = i;
            new Thread(() -> {
                while (true) {
                    f.update();
                    System.gc();
                    System.out.println(n + " updated");
                }
            }).start();
        }
    }

    public synchronized void update() {
        data = new ArrayList<>(1024 * 1024);
        for (int i = 0; i < 1024 * 1024; i++) {
            data.add(new String("hello"));
        }
    }
}
gh

因此,问题出在glibc的malloc领域众多,每个领域都有预分配内存的缓存。检查它是否是使用二进制运行的简单方法MALLOC_ARENA_MAX=2,但是最终解决方案取决于使用模式,有很多变量可以调整glibc的分配器:http : //man7.org/linux/man-pages/man3/mallopt.3.html

Java虚拟机实际上也受malloc的分配器影响。从我的经验来看,配置一些竞技场以防止在docker内部使用jvm占用大量内存是合适的。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

为什么带有200.000条记录的SELECT表使用过多的内存(+ 2GB)?

为什么Chrome使用过多的CPU?

为什么 OpenJDK Platform Binary 卡在打开并使用过多内存?

Keras 使用过多内存

重新分配时堆内存使用过多

为什么Ubuntu 14.04使用过多的RAM ..?

从线程无法访问所有使用过的堆时查找Java内存泄漏

Java 6内存使用过多

子线程中的malloc占用过多的虚拟内存

使用从镶木地板文件创建的dask数据帧时内存使用过多

FFmpeg重复拆分,选择和覆盖时使用过多的内存

从 Postgres 数据库获取数据时内存使用过多

在循环中使用反射类时,PHP占用过多内存的解决方法

Android约束布局使用过多的内存(RAM)(内存泄漏)

宣布全部时,ejabberd占用过多内存

为什么在使用多个线程来计算大型文件的单词频率时答案会有所不同?

IntelliJ Idea 社区版使用过多内存

在程序使用过多内存之前将其停止

使用过多内存的进化工厂

如何确定导致Visual Studio使用过多内存的原因?

熊猫通过read_sql_table使用过多内存

我们的虚拟主机已暂停我们使用过多的MySQL。有人知道为什么吗?

gvfsd占用过多内存

Firefox占用过多内存

projectRaster占用过多内存

'mov'的内存引用过多

为什么RestTemplate会消耗过多的内存?

为什么启动 Numba cuda 内核最多可使用 640 个线程,但在有大量可用的 GPU 内存时却以 641 个失败?

通过使用内联汇编程序用C调用golang函数时,对'mov'的内存引用过多