精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

如何提高 Ruby On Rails 性能

開發(fā) 后端
大家總是說 Rails 好慢啊,這差不多已經(jīng)成為 Ruby and Rails 社區(qū)里的一個(gè)老生常談的問題了。然而實(shí)際上這個(gè)說法并不正確。只要正確使用 Rails,把你的應(yīng)用運(yùn)行速度提升 10 倍并不困難。那么如何優(yōu)化你的應(yīng)用呢,我們來了解下面的內(nèi)容。

1 Introduction簡(jiǎn)介

大家總是說 Rails 好慢啊,這差不多已經(jīng)成為 Ruby and Rails 社區(qū)里的一個(gè)老生常談的問題了。然而實(shí)際上這個(gè)說法并不正確。只要正確使用 Rails,把你的應(yīng)用運(yùn)行速度提升 10 倍并不困難。那么如何優(yōu)化你的應(yīng)用呢,我們來了解下面的內(nèi)容。

[[151489]]

1.1 優(yōu)化一個(gè) Rails app 的步驟

導(dǎo)致你的 Rails 應(yīng)用變慢無非以下兩個(gè)原因:

  1. 在不應(yīng)該將 Ruby and Rails 作為首選的地方使用 Ruby and Rails。(用 Ruby and Rails 做了不擅長(zhǎng)做的工作)

  2. 過度的消耗內(nèi)存導(dǎo)致需要利用大量的時(shí)間進(jìn)行垃圾回收。

Rails 是個(gè)令人愉快的框架,而且 Ruby 也是一個(gè)簡(jiǎn)潔而優(yōu)雅的語言。但是如果它被濫用,那會(huì)相當(dāng)?shù)挠绊懶阅堋S泻芏喙ぷ鞑⒉贿m合用 Ruby and Rails,你最好使用其它的工具,比如,數(shù)據(jù)庫在大數(shù)據(jù)處理上優(yōu)勢(shì)明顯,R 語言特別適合做統(tǒng)計(jì)學(xué)相關(guān)的工作。

內(nèi)存問題是導(dǎo)致諸多 Ruby 應(yīng)用變慢的首要原因。Rails 性能優(yōu)化的 80-20 法則是這樣的:80% 的提速是源自于對(duì)內(nèi)存的優(yōu)化,剩下的 20% 屬于其它因素。為什么內(nèi)存消耗如此重要呢?因?yàn)槟惴峙涞膬?nèi)存越多,Ruby GC(Ruby 的垃圾回收機(jī)制)需要做的工作也就越多。Rails 就已經(jīng)占用了很大的內(nèi)存了,而且平均每個(gè)應(yīng)用剛剛啟動(dòng)后都要占用將近 100M 的內(nèi)存。如果你不注意內(nèi)存的控制,你的程序內(nèi)存增長(zhǎng)超過 1G 是很有可能的。需要回收這么多的內(nèi)存,難怪程序執(zhí)行的大部分時(shí)間都被 GC 占用了。

2 我們?nèi)绾问挂粋€(gè) Rails 應(yīng)用運(yùn)行更快?

有三種方法可以讓你的應(yīng)用更快:擴(kuò)容、緩存和代碼優(yōu)化。

擴(kuò)容在如今很容易實(shí)現(xiàn)。Heroku 基本上就是為你做這個(gè)的,而 Hirefire 則讓這一過程更加的自動(dòng)化。你可以在這個(gè)了 解到更多有關(guān)自動(dòng)擴(kuò)容的內(nèi)容。其它的托管環(huán)境提供了類似的解決方案。總之,可以的話你用它就是了。但是請(qǐng)牢記擴(kuò)容并不是一顆改善性能的銀彈。如果你的應(yīng)用 只需在 5 分鐘內(nèi)響應(yīng)一個(gè)請(qǐng)求,擴(kuò)容就沒有什么用。還有就是用 Heroku + Hirefire 幾乎很容易導(dǎo)致你的銀行賬戶透支。我已經(jīng)見識(shí)過 Hirefire 把我一個(gè)應(yīng)用的擴(kuò)容至 36 個(gè)實(shí)體,讓我為此支付了 $3100。我立馬就手動(dòng)吧實(shí)例減容到了 2 個(gè), 并且對(duì)代碼進(jìn)行了優(yōu)化.

Rails 緩存也很容易實(shí)施。Rails 4 中的塊緩存非常不錯(cuò)。Rails 文檔 是有關(guān)緩存知識(shí)的優(yōu)秀資料。另外還有一篇 Cheyne Wallace 有關(guān) Rails 性能的文章 也值得一讀。如今設(shè)置 Memcached 也簡(jiǎn)單。不過同擴(kuò)容相比,緩存并不能成為性能問題的終極解決方案。如果你的代碼無法理想的運(yùn)行,那么你將發(fā)現(xiàn)自己會(huì)把越來越多的資源耗費(fèi)在緩存上,直到緩存再也不能帶來速度的提升。

讓你的 Rails 應(yīng)用更快的唯一可靠的方式就是代碼優(yōu)化。在 Rails 的場(chǎng)景中這就是內(nèi)存優(yōu)化。而理所當(dāng)然的是,如果你接受了我的建議,并且避免把 Rails 用于它的設(shè)計(jì)能力范圍之外,你就會(huì)有更少的代碼要優(yōu)化。

2.1 避免內(nèi)存密集型Rails特性

Rails 一些特性花費(fèi)很多內(nèi)存導(dǎo)致額外的垃圾收集。列表如下。

2.1.1 序列化程序

序列化程序是從數(shù)據(jù)庫讀取的字符串表現(xiàn)為 Ruby 數(shù)據(jù)類型的實(shí)用方法。

  1. class Smth < ActiveRecord::Base 
  2.   serialize :data, JSON 
  3. end 
  4. Smth.find(...).data 
  5. Smth.find(...).data = { ... } 
  6. But convenience comes with 3x memory overhead. If you store 100M in data column, expect to allocate 300M just to read it from the database. 

它要消耗更多的內(nèi)存去有效的序列化,你自己看:

  1. class Smth < ActiveRecord::Base 
  2.   def data 
  3.     JSON.parse(read_attribute(:data)) 
  4.   end 
  5.   def data=(value) 
  6.     write_attribute(:data, value.to_json) 
  7.   end 
  8. end 

這將只要 2 倍的內(nèi)存開銷。有些人,包括我自己,看到 Rails 的 JSON 序列化程序內(nèi)存泄漏,大約每個(gè)請(qǐng)求 10% 的數(shù)據(jù)量。我不明白這背后的原因。我也不知道是否有一個(gè)可復(fù)制的情況。如果你有經(jīng)驗(yàn),或者知道怎么減少內(nèi)存,請(qǐng)告訴我。

2.1.2 活動(dòng)記錄

很容易與 ActiveRecord 操縱數(shù)據(jù)。但是 ActiveRecord 本質(zhì)是包裝了你的數(shù)據(jù)。如果你有 1g 的表數(shù)據(jù),ActiveRecord 表示將要花費(fèi) 2g,在某些情況下更多。是的,90% 的情況,你獲得了額外的便利。但是有的時(shí)候你并不需要,比如,批量更新可以減少 ActiveRecord 開銷。下面的代碼,即不會(huì)實(shí)例化任何模型,也不會(huì)運(yùn)行驗(yàn)證和回調(diào)。

Book.where('title LIKE ?', '%Rails%').update_all(author: 'David')

后面的場(chǎng)景它只是執(zhí)行 SQL 更新語句。

  1. update books 
  2.   set author = 'David' 
  3.   where title LIKE '%Rails%' 
  4. Another example is iteration over a large dataset. Sometimes you need only the data. No typecasting, no updates. This snippet just runs the query and avoids ActiveRecord altogether: 
  5. result = ActiveRecord::Base.execute 'select * from books' 
  6. result.each do |row| 
  7.   # do something with row.values_at('col1''col2'
  8. end 

2.1.3 字符串回調(diào)

Rails 回調(diào)像之前/之后的保存,之前/之后的動(dòng)作,以及大量的使用。但是你寫的這種方式可能影響你的性能。這里有 3 種方式你可以寫,比如:在保存之前回調(diào):

  1. before_save :update_status 
  2. before_save do |model| 
  3. model.update_status 
  4. end 
  5. before_save “self.update_status” 

前兩種方式能夠很好的運(yùn)行,但是第三種不可以。為什么呢?因?yàn)閳?zhí)行 Rails 回調(diào)需要存儲(chǔ)執(zhí)行上下文(變量,常量,全局實(shí)例等等)就是在回調(diào)的時(shí)候。如果你的應(yīng)用很大,你最終在內(nèi)存里復(fù)制了大量的數(shù)據(jù)。因?yàn)榛卣{(diào)在任何時(shí)候都可以執(zhí)行,內(nèi)存在你程序結(jié)束之前不可以回收。

有象征,回調(diào)在每個(gè)請(qǐng)求為我節(jié)省了 0.6 秒。

#p#

2.2 寫更少的 Ruby

這是我最喜歡的一步。我的大學(xué)計(jì)算機(jī)科學(xué)類教授喜歡說,最好的代碼是不存在的。有時(shí)候做好手頭的任務(wù)需要其它的工具。最常用的是數(shù)據(jù)庫。為什么呢? 因?yàn)?Ruby 不善于處理大數(shù)據(jù)集。非常非常的糟糕。記住,Ruby 占用非常大的內(nèi)存。所以舉個(gè)例子,處理 1G 的數(shù)據(jù)你可能需要 3G 的或者更多的內(nèi)存。它將要花費(fèi)幾十秒的時(shí)間去垃圾回收這 3G。好的數(shù)據(jù)庫可以一秒處理這些數(shù)據(jù)。讓我來舉一些例子。

2.2.1 屬性預(yù)加載

有時(shí)候反規(guī)范化模型的屬性從另外一個(gè)數(shù)據(jù)庫獲取。比如,想象我們正在構(gòu)建一個(gè) TODO 列表,包括任務(wù)。每個(gè)任務(wù)可以有一個(gè)或者幾個(gè)標(biāo)簽標(biāo)記。規(guī)范化數(shù)據(jù)模型是這樣的:

  1. Tasks 
  2.  id 
  3.  name 
  4. Tags 
  5.  id 
  6.  name 
  7. Tasks_Tags 
  8.  tag_id 
  9.  task_id 

加載任務(wù)以及它們的 Rails 標(biāo)簽,你會(huì)這樣做:

tasks = Task.find(:all, :include => :tags)
    > 0.058 sec

這段代碼有問題,它為每個(gè)標(biāo)簽創(chuàng)建了對(duì)象,花費(fèi)很多內(nèi)存。可選擇的解決方案,將標(biāo)簽在數(shù)據(jù)庫預(yù)加載。

  1. tasks = Task.select <<-END 
  2.       *, 
  3.       array( 
  4.         select tags.name from tags inner join tasks_tags on (tags.id = tasks_tags.tag_id) 
  5.         where tasks_tags.task_id=tasks.id 
  6.       ) as tag_names 
  7.     END 
  8.     > 0.018 sec 

這只需要內(nèi)存存儲(chǔ)額外一列,有一個(gè)數(shù)組標(biāo)簽。難怪快 3 倍。

2.2.2 數(shù)據(jù)集合

我所說的數(shù)據(jù)集合任何代碼去總結(jié)或者分析數(shù)據(jù)。這些操作可以簡(jiǎn)單的總結(jié),或者一些更復(fù)雜的。以小組排名為例。假設(shè)我們有一個(gè)員工,部門,工資的數(shù)據(jù)集,我們要計(jì)算員工的工資在一個(gè)部門的排名。

  1. SELECT * FROM empsalary; 
  2.   depname  | empno | salary 
  3. -----------+-------+------- 
  4.  develop   |     6 |   6000 
  5.  develop   |     7 |   4500 
  6.  develop   |     5 |   4200 
  7.  personnel |     2 |   3900 
  8.  personnel |     4 |   3500 
  9.  sales     |     1 |   5000 
  10.  sales     |     3 |   4800 

你可以用 Ruby 計(jì)算排名:

  1. salaries = Empsalary.all 
  2. salaries.sort_by! { |s| [s.depname, s.salary] } 
  3. key, counter = nil, nil 
  4. salaries.each do |s| 
  5.  if s.depname != key 
  6.   key, counter = s.depname, 0 
  7.  end 
  8.  counter += 1 
  9.  s.rank = counter 
  10. end 

Empsalary 表里 100K 的數(shù)據(jù)程序在 4.02 秒內(nèi)完成。替代 Postgres 查詢,使用 window 函數(shù)做同樣的工作在 1.1 秒內(nèi)超過 4 倍。

  1. SELECT depname, empno, salary, rank() 
  2. OVER (PARTITION BY depname ORDER BY salary DESC) 
  3. FROM empsalary; 
  4.   depname  | empno | salary | rank  
  5. -----------+-------+--------+------ 
  6.  develop   |     6 |   6000 |    1 
  7.  develop   |     7 |   4500 |    2 
  8.  develop   |     5 |   4200 |    3 
  9.  personnel |     2 |   3900 |    1 
  10.  personnel |     4 |   3500 |    2 
  11.  sales     |     1 |   5000 |    1 
  12.  sales     |     3 |   4800 |    2 

4 倍加速已經(jīng)令人印象深刻,有時(shí)候你得到更多,到 20 倍。從我自己經(jīng)驗(yàn)舉個(gè)例子。我有一個(gè)三維 OLAP 多維數(shù)據(jù)集與 600k 數(shù)據(jù)行。我的程序做了切片和聚合。在 Ruby 中,它花費(fèi)了 1G 的內(nèi)存大約 90 秒完成。等價(jià)的 SQL 查詢?cè)?5 內(nèi)完成。

#p#

2.3 優(yōu)化 Unicorn

如果你正在使用Unicorn,那么以下的優(yōu)化技巧將會(huì)適用。Unicorn 是 Rails 框架中最快的 web 服務(wù)器。但是你仍然可以讓它更運(yùn)行得快一點(diǎn)。

2.3.1 預(yù)載入 App 應(yīng)用

Unicorn 可以在創(chuàng)建新的 worker 進(jìn)程前,預(yù)載入 Rails 應(yīng)用。這樣有兩個(gè)好處。第一,主線程可以通過寫入時(shí)復(fù)制的友好GC機(jī)制(Ruby 2.0以上),共享內(nèi)存的數(shù)據(jù)。操作系統(tǒng)會(huì)透明的復(fù)制這些數(shù)據(jù),以防被worker修改。第二,預(yù)載入減少了worker進(jìn)程啟動(dòng)的時(shí)間。Rails worker進(jìn)程重啟是很常見的(稍后將進(jìn)一步闡述),所以worker重啟的速度越快,我們就可以得到更好的性能。

若需要開啟應(yīng)用的預(yù)載入,只需要在unicorn的配置文件中添加一行:

preload_app true

2.3.2 在 Request 請(qǐng)求間的 GC

請(qǐng)謹(jǐn)記,GC 的處理時(shí)間最大會(huì)占到應(yīng)用時(shí)間的50%。這個(gè)還不是唯一的問題。GC 通常是不可預(yù)知的,并且會(huì)在你不想它運(yùn)行的時(shí)候觸發(fā)運(yùn)行。那么,你該怎么處理?

首先我們會(huì)想到,如果完全禁用 GC 會(huì)怎么樣?這個(gè)似乎是個(gè)很糟糕的想法。你的應(yīng)用很可能很快就占滿 1G 的內(nèi)存,而你還未能及時(shí)發(fā)現(xiàn)。如果你服務(wù)器還同時(shí)運(yùn)行著幾個(gè) worker,那么你的應(yīng)用將很快會(huì)出現(xiàn)內(nèi)存不足,即使你的應(yīng)用是在自托管的服務(wù)器。更不用說只有 512M 內(nèi)存限制的 Heroku。

其實(shí)我們有更好的辦法。那么如果我們無法回避GC,我們可以嘗試讓GC運(yùn)行的時(shí)間點(diǎn)盡量的確定,并且在閑時(shí)運(yùn)行。例如,在兩個(gè)request之間,運(yùn)行GC。這個(gè)很容易通過配置Unicorn實(shí)現(xiàn)。

對(duì)于Ruby 2.1以前的版本,有一個(gè)unicorn模塊叫做OobGC:

require 'unicorn/oob_gc'
    use(Unicorn::OobGC, 1)   # "1" 表示"強(qiáng)制GC在1個(gè)request后運(yùn)行"

對(duì)于Ruby 2.1及以后的版本,最好使用gctools(https://github.com/tmm1/gctools):

  1. require 'gctools/oobgc' 
  2. use(GC::OOB::UnicornMiddleware) 

但在request之間運(yùn)行GC也有一些注意事項(xiàng)。最重要的是,這種優(yōu)化技術(shù)是可感知的。也就是說,用戶會(huì)明顯感覺到性能的提升。但是服務(wù)器需要做 更多的工作。不同于在需要時(shí)才運(yùn)行GC,這種技術(shù)需要服務(wù)器頻繁的運(yùn)行GC. 所以,你要確定你的服務(wù)器有足夠的資源來運(yùn)行GC,并且在其他worker 正在運(yùn)行GC的過程中,有足夠的worker來處理用戶的請(qǐng)求。

2.4 有限的增長(zhǎng)

我已經(jīng)給你展示了一些應(yīng)用會(huì)占用1G內(nèi)存的例子。如果你的內(nèi)存是足夠的,那么占用這么一大塊內(nèi)存并不是個(gè)大問題。但是Ruby可能不會(huì)把這塊內(nèi)存返還給操作系統(tǒng)。接下來讓我來闡述一下為什么。

Ruby通過兩個(gè)堆來分配內(nèi)存。所有Ruby的對(duì)象在存儲(chǔ)在Ruby自己的堆當(dāng)中。每個(gè)對(duì)象占用40字節(jié)(64位操作系統(tǒng)中)。當(dāng)對(duì)象需要更多內(nèi)存 的時(shí)候,它就會(huì)在操作系統(tǒng)的堆中分配內(nèi)存。當(dāng)對(duì)象被垃圾回收并釋放后,被占用的操作系統(tǒng)中的堆的內(nèi)存將會(huì)返還給操作系統(tǒng),但是Ruby自有的堆當(dāng)中占用的 內(nèi)存只會(huì)簡(jiǎn)單的標(biāo)記為free可用,并不會(huì)返還給操作系統(tǒng)。

這意味著,Ruby的堆只會(huì)增加不會(huì)減少。想象一下,如果你從數(shù)據(jù)庫讀取了1百萬行記錄,每行10個(gè)列。那么你需要至少分配1千萬個(gè)對(duì)象來存儲(chǔ)這些 數(shù)據(jù)。通常Ruby worker在啟動(dòng)后占用100M內(nèi)存。為了適應(yīng)這么多數(shù)據(jù),worker需要額外增加400M的內(nèi)存(1千萬個(gè)對(duì)象,每個(gè)對(duì)象占用40個(gè)字節(jié))。即使這 些對(duì)象最后被收回,這個(gè)worker仍然使用著500M的內(nèi)存。

這里需要聲明, Ruby GC可以減少這個(gè)堆的大小。但是我在實(shí)戰(zhàn)中還沒發(fā)現(xiàn)有這個(gè)功能。因?yàn)樵谏a(chǎn)環(huán)境中,觸發(fā)堆減少的條件很少會(huì)出現(xiàn)。

如果你的worker只能增長(zhǎng),最明顯的解決辦法就是每當(dāng)它的內(nèi)存占用太多的時(shí)候,就重啟該worker。某些托管的服務(wù)會(huì)這么做,例如Heroku。讓我們來看看其他方法來實(shí)現(xiàn)這個(gè)功能。

2.4.1 內(nèi)部?jī)?nèi)存控制

Trust in God, but lock your car 相信上帝,但別忘了鎖車。(寓意:大部分外國(guó)人都有宗教信仰,相信上帝是萬能的,但是日常生活中,誰能指望上帝能幫助自己呢。信仰是信仰,但是有 困難的時(shí)候 還是要靠自己。)。有兩個(gè)途徑可以讓你的應(yīng)用實(shí)現(xiàn)自我內(nèi)存限制。我管他們做,Kind(友好)和hard(強(qiáng)制).

Kind 友好內(nèi)存限制是在每個(gè)請(qǐng)求后強(qiáng)制內(nèi)存大小。如果worker占用的內(nèi)存過大,那么該worker就會(huì)結(jié)束,并且unicorn會(huì)創(chuàng)建一個(gè)新的worker。這就是為什么我管它做“kind”。它不會(huì)導(dǎo)致你的應(yīng)用中斷。

獲取進(jìn)程的內(nèi)存大小,使用 RSS 度量在 Linux 和 MacOS 或者 OS gem 在 windows 上。我來展示下在 Unicorn 配置文件里怎么實(shí)現(xiàn)這個(gè)限制:

  1. class Unicorn::HttpServer 
  2.  KIND_MEMORY_LIMIT_RSS = 150 #MB 
  3.  alias process_client_orig process_client 
  4.  undef_method :process_client 
  5.  def process_client(client) 
  6.   process_client_orig(client) 
  7.   rss = `ps -o rss= -p #{Process.pid}`.chomp.to_i / 1024 
  8.   exit if rss > KIND_MEMORY_LIMIT_RSS 
  9.  end 
  10. end 

硬盤內(nèi)存限制是通過詢問操作系統(tǒng)去殺你的工作進(jìn)程,如果它增長(zhǎng)很多。在 Unix 上你可以叫 setrlimit 去設(shè)置 RSSx 限制。據(jù)我所知,這種只在 Linux 上有效。MacOS 實(shí)現(xiàn)被打破了。我會(huì)感激任何新的信息。

這個(gè)片段來自 Unicorn 硬盤限制的配置文件:

  1. after_fork do |server, worker| 
  2.   worker.set_memory_limits 
  3. end 
  4. class Unicorn::Worker 
  5.   HARD_MEMORY_LIMIT_RSS = 600 #MB 
  6.   def set_memory_limits 
  7.     Process.setrlimit(Process::RLIMIT_AS, HARD_MEMORY_LIMIT * 1024 * 1024
  8.   end 
  9. end 

2.4.2 外部?jī)?nèi)存控制

自動(dòng)控制沒有從偶爾的 OMM(內(nèi)存不足)拯救你。通常你應(yīng)該設(shè)置一些外部工具。在 Heroku 上,沒有必要因?yàn)樗鼈冇凶约旱谋O(jiān)控。但是如果你是自托管,使用 monitgod 是一個(gè)很好的主意,或者其它的監(jiān)視解決方案。

#p#

2.5 優(yōu)化 Ruby GC

在某些情況下,你可以調(diào)整 Ruby GC 來改善其性能。我想說,這些 GC 調(diào)優(yōu)變得越來越不重要,Ruby 2.1 的默認(rèn)設(shè)置,后來已經(jīng)對(duì)大多數(shù)人有利。

GC 好的調(diào)優(yōu)你需要知道它是怎么工作的。這是一個(gè)獨(dú)立的主題,不屬于這編文章。要了解更多,徹底讀讀 Sam Saffron 的 揭秘 Ruby GC 這篇文章。在我即將到來的 Ruby 性能的一書,我挖到更深的 Ruby GC 細(xì)節(jié)。訂閱這個(gè),當(dāng)我完成這本書的 beta 版本會(huì)給你發(fā)送一份郵件。

我的建議是最好不要改變 GC 的設(shè)置,除非你明確知道你想要做什么,而且有足夠的理論知識(shí)知道如何提高性能。對(duì)于使用 Ruby 2.1 或之后的版本的用戶,這點(diǎn)尤為重要。

我知道只有一種場(chǎng)合 GC 優(yōu)化確實(shí)能帶來性能的提升。那就是,當(dāng)你要一次過載入大量的數(shù)據(jù)。你可以通過改變?nèi)缦碌沫h(huán)境變量來達(dá)到減少GC運(yùn)行的頻 率:RUBY_GC_HEAP_GROWTH_FACTOR,RUBY_GC_MALLOC_LIMIT,RUBY_GC_MALLOC_LIMIT_MAX,RUBY_GC_OLDMALLOC_LIMIT, 和 RUBY_GC_OLDMALLOC_LIMIT。

請(qǐng)注意,這些變量只適用于 Ruby 2.1 及之后的版本。對(duì)于 2.1 之前的版本,可能缺少某一個(gè)變量,或者變量不是使用這個(gè)名字。

RUBY_GC_HEAP_GROWTH_FACTOR 默認(rèn)值 1.8,它用于當(dāng) Ruby 的堆沒有足夠的空間來分配內(nèi)存的時(shí)候,每次應(yīng)該增加多少。當(dāng)你需要使用大量的對(duì)象的時(shí)候,你希望堆的內(nèi)存空間增長(zhǎng)的快一點(diǎn)。在這種場(chǎng)合,你需要增加該因子的大小。

內(nèi)存限制是用于定義當(dāng)你需要向操作系統(tǒng)的堆申請(qǐng)空間的時(shí)候,GC 被觸發(fā)的頻率。Ruby 2.1 及之后的版本,默認(rèn)的限額為:

  1. New generation malloc limit RUBY_GC_MALLOC_LIMIT 16M 
  2. Maximum new generation malloc limit RUBY_GC_MALLOC_LIMIT_MAX 32M 
  3. Old generation malloc limit RUBY_GC_OLDMALLOC_LIMIT 16M 
  4. Maximum old generation malloc limit RUBY_GC_OLDMALLOC_LIMIT_MAX 128M 

讓我簡(jiǎn)要的說明一下這些值的意義。通過設(shè)置以上的值,每次新對(duì)象分配 16M 到 32M 之間,并且舊對(duì)象每占用 16M 到 128M 之間的時(shí)候 (“舊對(duì)象” 的意思是,該對(duì)象至少被垃圾回收調(diào)用過一次), Ruby 將運(yùn)行 GC。Ruby 會(huì)根據(jù)你的內(nèi)存模式,動(dòng)態(tài)的調(diào)整當(dāng)前的限額值。

所以,當(dāng)你只有少數(shù)幾個(gè)對(duì)象,卻占用了大量的內(nèi)存(例如讀取一個(gè)很大的文件到字符串對(duì)象中),你可以增加該限額,以減少 GC 被觸發(fā)的頻率。請(qǐng)記住,要同時(shí)增加 4 個(gè)限額值,而且最好是該默認(rèn)值的倍數(shù)。

我的建議是可能和其他人的建議不一樣。對(duì)我可能合適,但對(duì)于你卻未必。這些文章將介紹,哪些對(duì) Twitter 適用,而哪些對(duì) Discourse 適用。

2.6 Profile

有時(shí)候,這些建議未必就是通用。你需要弄清楚你的問題。這時(shí)候,你就要使用 profiler。Ruby-Prof 是每個(gè) Ruby 用戶都會(huì)使用的工具。

想知道更多關(guān)于 profiling 的知識(shí), 請(qǐng)閱讀 Chris Heald’s 和我的關(guān)于在 Rails 中 使用ruby-prof 的文章。還有一些也許有點(diǎn)過時(shí)的關(guān)于 memory profiling 的建議.

2.7 編寫性能測(cè)試用例

最后,提高 Rails 性能的技巧中,雖然不是最重要的,就是確認(rèn)應(yīng)用的性能不會(huì)因你修改了代碼而導(dǎo)致性能再次下降。Rails 3.x 有一個(gè)附帶了一個(gè) 性能測(cè)試和 profiling 框架 的功能。對(duì)于 Rails 4, 你可以通過 rails-perftest gem 使用相同的框架。

3 總結(jié)感言

對(duì)于一篇文章中,對(duì)于如何提高 Ruby 和 Rails 的性能,要面面俱到,確實(shí)不可能。所以,在這之后,我會(huì)通過寫一本書來總結(jié)我的經(jīng)驗(yàn)。如果你覺得我的建議有用,請(qǐng)登記 mailinglist ,當(dāng)我準(zhǔn)備好了該書的預(yù)覽版之后,將會(huì)第一時(shí)間通知你。現(xiàn)在,讓我們一起來動(dòng)手,讓 Rails 應(yīng)用跑得更快一些吧!

責(zé)任編輯:王雪燕 來源: oschina
相關(guān)推薦

2015-10-14 17:27:18

性能

2009-12-16 15:23:33

Ruby on rai

2010-07-12 09:22:05

RubyRuby on rai

2009-08-27 10:21:22

Ruby on Rai

2009-12-16 15:14:43

Ruby on Rai

2009-12-16 17:07:27

Ruby on Rai

2009-12-14 15:37:35

Ruby on Rai

2009-12-18 11:14:26

Ruby On Rai

2009-08-06 09:13:36

Ruby on Rai

2009-12-16 17:00:43

Ruby on Rai

2009-12-17 14:29:50

Ruby on Rai

2009-12-14 15:30:43

安裝Ruby on R

2009-12-16 16:37:59

Ruby on Rai

2009-12-16 17:50:58

Ruby on Rai

2009-12-17 17:37:42

Ruby on Rai

2009-12-16 17:37:31

Ruby on Rai

2010-09-25 14:39:29

Bruce Tate

2009-12-16 15:41:10

Ruby on Rai

2013-03-28 12:42:02

RubyRails

2010-10-09 08:58:03

NginxRuby on Rai
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

无遮挡又爽又刺激的视频| 91精品视频一区| 少妇精品一区二区三区| 日本一区二区三区视频在线| 欧美国产日韩精品免费观看| 亚洲bt欧美bt日本bt| 日韩av在线天堂| 狠狠操综合网| 日韩视频永久免费| 久久婷婷国产精品| 成人av福利| 99久久精品免费看国产| 国产精品视频午夜| 日本一区二区不卡在线| 成人看的视频| 亚洲国产中文字幕久久网| 亚洲 欧美 日韩系列| 欧美大胆的人体xxxx| 久久久夜色精品亚洲| 亚洲最大av网站| 国产又粗又猛又黄视频| 国语对白精品一区二区| 国产午夜精品一区理论片飘花| 女王人厕视频2ⅴk| 深夜视频一区二区| 精品日本美女福利在线观看| 99热都是精品| 成人18在线| 91蜜桃视频在线| 成人午夜电影免费在线观看| 在线观看国产一区二区三区| 99热免费精品| 欧美精品性视频| 日韩av网站在线播放| 色婷婷久久久| 亚洲第一色在线| 中文字幕亚洲日本| 天天综合在线观看| 欧美性大战久久久久久久蜜臀| 亚洲国产成人精品无码区99| 污片视频在线免费观看| 国产精品成人免费在线| 日本一区高清在线视频| 日韩在线免费播放| 东方aⅴ免费观看久久av| 成人性教育视频在线观看| 国产美女www| 久久福利一区| 日本久久亚洲电影| www亚洲视频| 国产精品主播| 热99久久精品| 无码人妻久久一区二区三区| 另类激情亚洲| 国产99久久精品一区二区 夜夜躁日日躁 | 日韩限制级电影在线观看| 国产三级国产精品国产专区50| 日韩av中字| 欧美在线免费播放| wwww.国产| 免费一区二区三区四区| 欧美日韩精品免费| а 天堂 在线| 91精品国产自产在线丝袜啪| 日韩午夜电影在线观看| 国产a√精品区二区三区四区| 哺乳挤奶一区二区三区免费看| 精品国精品国产尤物美女| 95视频在线观看| 日本中文字幕在线一区| 亚洲乱码国产乱码精品精天堂| 偷拍女澡堂一区二区三区| 国产九一精品| 久热精品在线视频| 精品肉丝脚一区二区三区| 在线亚洲精品| 国产精品久久久久久av福利| 国产一区二区视频免费观看 | 国产精品久久久久久亚洲色| 日韩mv欧美mv国产网站| 亚洲欧美精品在线| 日本 欧美 国产| 亚洲一级网站| 日韩免费观看高清| 91成品人影院| 成人动漫av在线| 欧美日韩精品久久久免费观看| 91在线视频| 一区二区三区 在线观看视频| 亚洲熟妇国产熟妇肥婆| 国产精品久久久久久妇女| 日韩欧美国产小视频| jizz欧美性20| 91精品一区二区三区综合| 午夜精品三级视频福利| 18国产免费视频| 懂色av中文字幕一区二区三区| 美国av一区二区三区| 日本最黄一级片免费在线| 一区二区三区精品视频| 国产一级不卡毛片| 91亚洲无吗| 色一情一乱一区二区| 日韩污视频在线观看| 看国产成人h片视频| 国产高清在线一区| 午夜在线观看视频| 精品欧美激情精品一区| www.污污视频| 亚洲黄页网站| 欧美日韩国产第一页| 91视频在线视频| 成人免费观看视频| 午夜在线视频免费观看| 卡通欧美亚洲| 精品国产一二三| eeuss中文字幕| 亚洲一区久久| 国产中文一区二区| 中文字幕中文字幕在线中高清免费版| 欧美性猛交xxxx| 91精品又粗又猛又爽| 亚洲91中文字幕无线码三区| 国产成人91久久精品| 欧美一区二区三区激情| 亚洲欧美日韩一区二区| 国产精品视频分类| 久久99国产精品视频| 韩国国内大量揄拍精品视频| 精品国产乱码一区二区三 | 韩国三级在线一区| 水蜜桃亚洲精品| 电影一区二区三区| 日韩国产在线播放| 日韩欧美不卡视频| 成人av在线影院| 青青青青在线视频| 日韩在线视频一区二区三区| 日韩中文字幕在线视频| 五月激情丁香网| 国产日韩欧美电影| 欧美一级片中文字幕| 日韩精品免费一区二区夜夜嗨| 欧美精品18videos性欧美| 精品国产亚洲一区二区麻豆| 亚洲欧美日韩中文字幕一区二区三区| 鲁一鲁一鲁一鲁一av| 日本一区二区在线看| 国产精品盗摄久久久| av在线免费一区| 欧美日韩精品一区视频| 一二三四在线观看视频| 蜜桃精品在线观看| 日本特级黄色大片| 日韩视频一二区| 欧美激情一区二区三级高清视频| 丰满大乳国产精品| 亚洲成av人片| 久久精品国产亚洲AV熟女| 国产精品一国产精品k频道56| 麻豆91av| 国产韩日精品| 久热精品视频在线观看| 黑人乱码一区二区三区av| 亚洲第一福利一区| 欧美做受喷浆在线观看| 日日夜夜精品视频免费| 亚洲欧美日韩另类精品一区二区三区 | 一级片黄色免费| 国内精品美女在线观看| 久久久久久久久久久久久久一区| 欧美xxx视频| 日韩中文在线不卡| 国产成人精品无码高潮| 午夜精品视频在线观看| 91l九色lporny| 精品一区二区av| av免费看网址| 欧美军人男男激情gay| 91社区国产高清| 91av久久| 中文欧美日本在线资源| 国内精品国产成人国产三级| 欧美日韩国产精品一区二区三区四区 | 亚洲国产精品久久不卡毛片| 亚洲一级中文字幕| 精品午夜久久福利影院| 人妻无码久久一区二区三区免费| 亚洲精品国产setv| 成人激情视频网| 2020国产在线| 日韩在线视频线视频免费网站| 欧美综合视频在线| 91九色最新地址| a级片在线观看免费| 久久蜜桃一区二区| 91欧美一区二区三区| 美女国产精品| 欧美日韩视频免费| 成人羞羞视频在线看网址| 风间由美一区二区三区| 国产精品美女午夜爽爽| 国模私拍一区二区三区| 素人av在线| 亚洲欧美在线一区二区| www.桃色av嫩草.com| 欧美在线观看你懂的| 国产精品a成v人在线播放| 国产精品美女久久久久久久久久久 | 99综合电影在线视频| 亚洲36d大奶网| 国产一区二区你懂的| japanese在线播放| 成人一区二区| 久久久久资源| 成人在线tv视频| 亚洲va欧美va国产综合剧情| 日本欧美日韩| 91国内产香蕉| 岛国毛片av在线| 久久视频在线免费观看| 国产精品影院在线| 精品亚洲一区二区三区在线播放| 国产又黄又粗又硬| 欧美色网站导航| 无码人妻久久一区二区三区| 岛国视频午夜一区免费在线观看| 亚洲色婷婷一区二区三区| 国产精品嫩草影院com| 91中文字幕永久在线| 成人久久久精品乱码一区二区三区| 波多野结衣国产精品| 蜜桃精品视频在线| 国产一级特黄a大片免费| 鲁大师成人一区二区三区| 国产免费黄视频| 亚洲美女网站| 国产 日韩 亚洲 欧美| 在线观看视频免费一区二区三区| 亚洲区成人777777精品| 久久久久久久久久久9不雅视频 | seseavlu视频在线| 亚洲日本中文字幕| 男人天堂资源在线| 亚洲久久久久久久久久久| 亚洲欧美自偷自拍| 亚洲九九九在线观看| 经典三级在线| 亚洲最新av在线网站| 国产精品一区在线看| 在线看欧美日韩| av在线免费播放网站| 中文字幕亚洲第一| 日韩黄色影院| 久久99久国产精品黄毛片入口| 图片区小说区亚洲| 久久免费视频网| 日韩精品极品| 国产成人亚洲综合| 成人高清一区| 91在线无精精品一区二区| 久久久久久爱| 激情一区二区三区| 精品久久91| www亚洲国产| 黄色一区二区三区四区| 色综合久久久久无码专区| 亚洲欧美高清| 三上悠亚在线一区二区| 国产大陆a不卡| 精品夜夜澡人妻无码av | 杨钰莹一级淫片aaaaaa播放| 亚洲综合在线观看视频| 全部毛片永久免费看| 欧美在线不卡一区| hs视频在线观看| 国产午夜精品理论片a级探花| 国产香蕉视频在线看| 久久久极品av| 美女高潮视频在线看| 国产精品你懂得| 一区二区亚洲视频| 日韩精品国内| 欧美精品国产一区| 中文字幕乱码人妻综合二区三区| 激情综合五月天| 菠萝菠萝蜜网站| 国产精品成人免费| 九九热精品视频在线| 91精品国产综合久久蜜臀| 色欲av永久无码精品无码蜜桃| 国产午夜精品全部视频在线播放 | 国产精品久久久久av| 51社区在线成人免费视频| 日本一区二区三不卡| 亚洲视频一区| 天天干天天操天天做| av资源网一区| 麻豆精品一区二区三区视频| 91久久国产综合久久| 人妻无码一区二区三区久久99| 亚洲视频免费一区| 国产桃色电影在线播放| 国产成人福利网站| 超碰在线成人| 自拍偷拍亚洲色图欧美| 久久久久久穴| 欧美xxxxx精品| 亚洲乱码中文字幕| 中文字幕 国产精品| 日韩电影第一页| 羞羞视频在线观看不卡| 国产精品夜色7777狼人| 台湾佬综合网| www.国产在线播放| 激情欧美一区二区| 摸摸摸bbb毛毛毛片| 欧美日韩国产一区二区三区| 99精品在线看| 日韩在线观看免费网站| 成人免费看黄| 久久精品中文字幕一区二区三区| 欧美先锋影音| 日日夜夜精品视频免费观看| 中文字幕一区二区三区不卡在线| 91视频久久久| 亚洲欧美资源在线| 波多视频一区| 蜜桃精品久久久久久久免费影院 | 亚洲色图欧美自拍| 国产精品麻豆久久久| 波多野结衣在线观看一区| 亚洲码在线观看| 亚洲小少妇裸体bbw| 久久精品国产精品青草色艺| 99精品免费| 91精品国产自产| 欧美午夜精品久久久久久浪潮| 性xxxx视频| 欧美一级片久久久久久久| 卡通动漫国产精品| 免费无码毛片一区二三区| 99视频在线精品| 久久久久久久久久影院| 亚洲福利视频在线| 欧美私密网站| 青青成人在线| 蜜臀久久99精品久久久画质超高清| 极品人妻videosss人妻| 欧美性猛交xxxxxx富婆| 久操视频在线免费播放| 91精品视频一区| 欧美精品自拍| 五月开心播播网| 日本少妇高清视频| 精品国产一区二区在线观看| 91禁在线看| 欧美日韩最好看的视频| 日本伊人午夜精品| www.xx日本| 日韩精品一区二区三区中文精品 | 国产98色在线| 97色伦图片97综合影院| 日韩欧美中文视频| 亚洲国产美女搞黄色| 青青草视频在线免费观看| 国产精品免费一区| 欧美黄色一区| 自拍视频一区二区| 欧美亚洲动漫精品| av网址在线免费观看| 国产午夜精品一区| 日日夜夜免费精品| 性色av无码久久一区二区三区| 亚洲成人精品av| 欧美日韩女优| 成人一级生活片| 国产欧美精品一区aⅴ影院| av中文字幕在线免费观看| 91av视频在线免费观看| 日韩成人精品一区二区| 真实乱偷全部视频| 欧美性猛交xxxx久久久| 精品国产丝袜高跟鞋| 国产综合18久久久久久| 久久成人av少妇免费| 国产成人啪精品午夜在线观看| 亚洲一区二区精品| 超碰在线成人| 艹b视频在线观看| 亚洲第一久久影院| 男人的天堂在线视频免费观看| 国产精品一区二区你懂得| 日本一不卡视频| 日本在线观看视频网站| www亚洲精品| 一个色免费成人影院| 四川一级毛毛片| 欧美四级电影在线观看| 麻豆理论在线观看|