成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

淺析深拷貝與淺拷貝以及寫時拷貝

系統(tǒng) Linux
今天分享一個高頻面試問題:深拷貝與淺拷貝以及寫時拷貝

[[374530]]

 今天分享一個高頻面試問題:深拷貝與淺拷貝以及寫時拷貝

假設B復制了A,當修改A時,看B是否會發(fā)生變化。如果B也跟著變了,說明這是淺拷貝;如果B沒變,那就是深拷貝。

1、淺拷貝:將原對象的引用直接賦給新對象,新對象只是原對象的一個引用。

2、深拷貝:創(chuàng)建一個新的對象和數(shù)組,將原對象的各項屬性的“值”(數(shù)組的所有元素)拷貝過來,是“值”而不是“引用”。

淺拷貝只是對指針的拷貝,拷貝后兩個指針指向同一個內存空間,深拷貝不但對指針進行拷貝,而且對指針指向的內容進行拷貝,經(jīng)深拷貝后的指針是指向兩個不同地址的指針。

3、寫時復制技術:最初產(chǎn)生于Unix系統(tǒng),用于實現(xiàn)一種傻瓜式的進程創(chuàng)建:當發(fā)出fork( )系統(tǒng)調用時,內核原樣復制父進程的整個地址空間并把復制的那一份分配給子進程。這種行為是非常耗時的,因為它需要:

· 為子進程的頁表分配頁面

· 為子進程的頁分配頁面

· 初始化子進程的頁表

· 把父進程的頁復制到子進程相應的頁中

創(chuàng)建一個地址空間的這種方法涉及許多內存訪問,消耗許多CPU周期,并且完全破壞了高速緩存中的內容。在大多數(shù)情況下,這樣做常常是毫無意義的,因為許多子進程通過裝入一個新的程序開始它們的執(zhí)行,這樣就完全丟棄了所繼承的地址空間。

現(xiàn)在的Unix內核(包括Linux),采用一種更為有效的方法稱之為寫時復制(或COW)。這種思想相當簡單:父進程和子進程共享頁面而不是復制頁面。然而,只要頁面被共享,它們就不能被修改。無論父進程和子進程何時試圖寫一個共享的頁面,就產(chǎn)生一個錯誤,這時內核就把這個頁復制到一個新的頁面中并標記為可寫。原來的頁面仍然是寫保護的:當其它進程試圖寫入時,內核檢查寫進程是否是這個頁面的唯一屬主;如果是,它把這個頁面標記為對這個進程是可寫的。

Linux的fork()使用寫時復制

傳統(tǒng)的fork()系統(tǒng)調用直接把所有的資源復制給新創(chuàng)建的進程。這種實現(xiàn)過于簡單并且效率低下,因為它拷貝的數(shù)據(jù)或許可以共享。更糟糕的是,如果新進程打算立即執(zhí)行一個新的映像,那么所有的拷貝都將前功盡棄。Linux的fork()使用寫時拷貝(copy-on-write)頁實現(xiàn)。

寫時拷貝是一種可以推遲甚至避免拷貝數(shù)據(jù)的技術。內核此時并不復制整個進程的地址空間,而是讓父子進程共享同一個地址空間。只用在需要寫入的時候才會復制地址空間,從而使各個進行擁有各自的地址空間。也就是說,資源的復制是在需要寫入的時候才會進行,在此之前,只有以只讀方式共享。這種技術使地址空間上的頁的拷貝被推遲到實際發(fā)生寫入的時候。在頁根本不會被寫入的情況下—例如,fork()后立即執(zhí)行exec(),地址空間就無需被復制了。fork()的實際開銷就是復制父進程的頁表以及給子進程創(chuàng)建一個進程描述符。在一般情況下,進程創(chuàng)建后都為馬上運行一個可執(zhí)行的文件,這種優(yōu)化,可以避免拷貝大量根本就不會被使用的數(shù)據(jù)(地址空間里常常包含數(shù)十兆的數(shù)據(jù))。由于Unix強調進程快速執(zhí)行的能力,所以這個優(yōu)化是很重要的。

COW技術初窺:

在Linux程序中,fork()會產(chǎn)生一個和父進程完全相同的子進程,但子進程在此后多會exec系統(tǒng)調用,出于效率考慮,linux中引入了“寫時復制“技術,也就是只有進程空間的各段的內容要發(fā)生變化時,才會將父進程的內容復制一份給子進程。

那么子進程的物理空間沒有代碼,怎么去取指令執(zhí)行exec系統(tǒng)調用呢?

在fork之后exec之前兩個進程用的是相同的物理空間(內存區(qū)),子進程的代碼段、數(shù)據(jù)段、堆棧都是指向父進程的物理空間,也就是說,兩者的虛擬空間不同,但其對應的物理空間是同一個。當父子進程中有更改相應段的行為發(fā)生時,再為子進程相應的段分配物理空間,如果不是因為exec,內核會給子進程的數(shù)據(jù)段、堆棧段分配相應的物理空間(至此兩者有各自的進程空間,互不影響),而代碼段繼續(xù)共享父進程的物理空間(兩者的代碼完全相同)。而如果是因為exec,由于兩者執(zhí)行的代碼不同,子進程的代碼段也會分配單獨的物理空間。

在網(wǎng)上看到還有個細節(jié)問題就是,fork之后內核會通過將子進程放在隊列的前面,以讓子進程先執(zhí)行,以免父進程執(zhí)行導致寫時復制,而后子進程執(zhí)行exec系統(tǒng)調用,因無意義的復制而造成效率的下降。

 

責任編輯:姜華 來源: 嵌入式Linux系統(tǒng)開發(fā)
相關推薦

2009-05-19 17:28:44

深拷貝淺拷貝clone()

2023-05-17 08:42:46

深拷貝Golang

2020-10-12 08:35:22

JavaScript

2024-03-15 15:03:23

2020-06-23 08:41:47

JavaScript開發(fā)技術

2021-07-16 12:33:24

Javascript深拷貝淺拷貝

2017-08-16 13:30:05

Java深拷貝淺拷貝

2024-04-17 09:01:08

Python深拷貝淺拷貝

2019-02-25 08:58:16

Python深拷貝淺拷貝

2021-09-27 11:07:11

深拷貝淺拷貝內存

2022-07-26 08:07:03

Python淺拷貝深拷貝

2022-11-07 11:37:27

深拷貝淺拷貝底層

2024-02-05 22:56:16

C++拷貝開發(fā)

2020-08-03 08:24:26

原型模式拷貝

2023-09-22 12:21:33

Python深拷貝淺拷貝

2025-04-27 09:45:58

JavaScript深拷貝淺拷貝

2021-10-18 09:01:01

前端賦值淺拷貝

2018-09-26 14:37:17

JavaScript前端編程語言

2021-06-28 07:12:28

賦值淺拷貝深拷貝

2021-09-10 07:41:06

Python拷貝Python基礎
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 久久成| 91天堂| 亚洲国产成人精品在线 | 国色天香成人网 | v片网站| 日韩欧美在线观看 | 影音先锋成人资源 | 久久综合一区二区 | 91精品国产91久久久久久密臀 | 国产精品福利网站 | 欧美xxxx日本 | 亚洲国产精品99久久久久久久久 | 天天摸天天干 | 蜜桃毛片 | 午夜影院在线观看 | 日韩欧美一级片 | 国产精品国产三级国产aⅴ入口 | 天天操天天射天天舔 | 中文字幕电影在线观看 | 久久久久久艹 | 成人免费视屏 | 国产精品永久免费视频 | 国产区视频在线观看 | 黄色网址免费在线观看 | 国产精品欧美一区二区 | 午夜精品久久久久久久久久久久久 | 理论片午午伦夜理片影院 | 久久成人高清视频 | av黄色在线| 久久久久国产精品一区二区 | 欧美日韩亚洲国产综合 | 亚洲视频精品在线 | 一区二区在线观看免费视频 | 亚洲精品乱码久久久久久按摩 | 成人影院av| 国产精品国产精品国产专区不片 | 91精品国产乱码久久蜜臀 | 91国在线高清视频 | 欧美日韩在线一区二区三区 | 日韩二区| 国产精品不卡 |