java 共享内存ipc,IPC共享内存和线程内存之间的性能差异

小编典典

1)shmat()将本地进程虚拟内存映射到共享段。必须对每个共享内存地址执行此转换,并且相对于shm访问的数量而言,这种转换可能会花费大量成本。在多线程应用程序中,不需要额外的转换:所有VM地址都转换为物理地址,就像不访问共享内存的常规过程一样。

除了建立共享页的初始成本外,与常规内存访问相比,没有任何开销shmat()-在调用过程中填充页表-

在大多数类型的Linux中,每4KB共享内存为1页(4或8字节) 。

无论是共享页面分配还是在同一流程中分配,(所有相关比较)成本都相同。

2)共享内存段必须由内核以某种方式维护。我不知道“某种程度上”在性能方面意味着什么,但是例如,当拆除了与shm相连的所有进程时,shm段仍处于启动状态,并且最终可以由新启动的进程重新访问。在shm段的生存期内,内核必须至少检查某种程度的开销。

无论是否共享,内存的每个页面都具有一个“结构页面”,并带有有关该页面的一些数据。其中一项是参考计数。当将页面分配给进程时(无论是通过“

shmat”还是其他机制),引用计数都会增加。通过某种方式释放它时,引用计数将减少。如果减少的计数为零,则实际上释放了页面-否则“此后再也没有发生”。

与分配的任何其他内存相比,开销基本上为零。无论如何,相同的机制也用于页面的其他目的-例如,您有一个页面也被内核使用-

并且您的进程终止了,内核需要知道在释放该页面之前,不释放该页面,因为以及用户流程。

创建“叉子”时会发生同样的事情。派生一个进程时,父进程的整个页表实际上都将复制到子进程中,并且所有页都变为只读状态。每当发生写操作时,内核都会发生错误,从而导致该页面被复制-

因此该页面现在有两个副本,执行写操作的进程可以修改该页面,而不会影响其他进程。一旦子进程(或父进程)死亡,则当然这两个进程仍然拥有所有页面(例如,从未写入的代码空间,以及可能从未接触过的一堆公共数据,等等)显然无法释放,直到两个进程都“死”为止。同样,引用计数的页面在这里很有用,因为我们只对每个页面上的引用计数进行计数,

共享库确实发生了同样的事情。如果一个进程使用共享库,则该进程结束时将释放它。但是,如果两个,三个或100个进程使用同一个共享库,则代码显然必须保留在内存中,直到不再需要该页面为止。

因此,基本上,整个内核中的所有页面都已被引用计数。开销很少。

2020-06-03

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值