JVM知識在離線數據中的運用


  又是飛花的季節了。多愁善感的林妹妹看到柳絮說:“嫁與東風春不管,憑爾去,忍淹留。”寶姐姐看了卻來一句:“好風憑借力送我上青雲”。

  特別羡慕情商高的人,經常在想他們是怎么做到的。從來看不出他們不喜歡誰,滿眼里都是真誠。漸漸的開始能夠理解所有的人。比如:有些女孩愛化很濃的妝,后來才想到不是所有的人都天生皮膚細,清水洗把臉就可以出門。現實的女孩大都是夢碎之后被碎片扎的遍體鱗傷,更應該被呵護才是。愛錢是因為不是所有的人都有不依靠別人就能活的能力,誰最先想到的不是衣食住行呢。但我還是理解不了浪費糧食的,不管是植物還是動物,為了我付出了自己的生命,我好歹也應該讓它成為我身體的一部分,和它一起好好的活着~~

  我是一個心想事成的人,人生少走了很多彎路,少了很多思考,也少了很多對他人的理解。還好大腦的自動補全能力比較強。在超市里,我走到酒的那一排都會繞着走,因為總是感覺酒瓶子會掉下來碎掉。有次看《神盾局特工》看完了換一下節目才發現靜音了。因為之前看過好幾集了,看到字幕大腦里自動把聲音補上了,竟然沒發現。不知道這個能力和語言天賦之間有沒有什么聯系。但是我的大腦會存儲很多的聲音,很少存儲圖像。很少真正很關心一個人的長相。對於我,一個有磁性聲音的人會更有魅力。不知道這個和寫不好字的缺陷之間有沒有什么聯系[衰]。小鮮肉的這種能力在他一歲的時候就體現出來了。一個媽媽推着一個寶寶在前面走,他看到小推車上的水壺有一半在外面往下沉。他就大喊:要掉出來了,要掉出來了。別人沒怎么樣,他急得不行了。

  心想事成是一種性格,而不是能力。小鮮肉如果有想做的事兒,想要的東西,他很少直接說。他會非要別人去猜他怎么想的。我卻總是想辦法讓他自己說出來,因為這樣的一種做事方式,他會終生受益的。比如說:俞伯牙如果是我這樣的性格,來了一個人,不管是誰,他在彈琴,他就會說:我彈的高山,我彈的是流水。也就不會“知音難覓”一說了。這樣的人因為少了讓別人去理解自己這一步,所以更多會考慮怎么理解別人。這樣的人還很單純,單純的人臉上會獨有一種“笑起來很甜”。

  《小王子》里的小主人公整個人生都在探索自己為什么會愛上那朵玫瑰。那花兒長的美,卻矯情,虛榮,帶給了他無盡的痛苦。最后受到了小狐狸的啟發才發現:那花兒的獨一無二在於他對花兒的付出,花兒對自己的馴服。其實哪有那么糾結?愛了就愛了唄。

  在現實中,會是這樣一種情況。兩個男孩喜歡同一個女孩子。其中一個男孩總是在想:“我擁有什么資本能讓她對我不離不棄呢,我有沒有比另一個男孩更優秀,如果她看清楚了真實的我會不會不喜歡我?我的付出會不會一無所獲?她是不是一個好女孩?”另一個男孩只在想一件事,那就是我喜歡那個女孩子我要讓她知道。一個夠聰明的女孩子就算心里喜歡的前一個,無論理智還是情感,她也不會選他(碰上我這種愛給自己找麻煩的人另當別論[汗])。因為這樣人的性格產生的連鎖反應是:總是在權衡利弊,人會越來越自私,自我為中心,不願意付出。想的太多,做的太少,害怕承擔后果,這樣的人根本沒有真心去愛一個人的基本能力。而后一個男孩:想到就去做了,他會想各種方法去達到目的,做了很多,承擔了很多,會更有擔當和責任心。為啥我會想這些呢?好歹咱也是中科院心理學的研究生,不能白學啊!

  一定要相信周圍的人都是很聰明的,自己是什么樣的人,別人都是可以看出來的,所以也沒有什么必要藏着掖着的。想了很多,也總有自己沒有考慮到的因素。谷歌的對弈軟件也不能百分百分取勝。所以,只要去做自己想做的事兒就可以了,想多想少,結果可能沒有那么大的差別,失之東隅收之桑榆。做和不做,區別可就大了。

  小狐狸對小王子說:“如果你馴服了我,我的生命就會充滿陽光……我不吃面包,麥子對我本沒有什么意義,麥田更不會讓我產生聯想,可一旦你馴服了我,一切都改變了,因為你有金色的頭發,再看到麥田我就會想起你,而且我還會喜歡傾聽風吹滿麥浪的聲音……” 小狐狸忍受着最終會哭一場的后果讓小王子馴服了自己。最終小王子選擇了回去找自己的玫瑰。但是小狐狸的生命從此鮮活起來,一切都有了意義。

  額~~,說多了。在想離線數據這個項目的獨特之處在哪里。它用到了很多和JVM打交道的地方,順便將這個總結一下。

  我既然把內存參數配置設置成了這個樣子。我當然要知道這么龐大的資源都干了啥。特別是半夜跑全量的時候,我有次測試了一晚上,第二天早上睡覺中午醒來發現那台機器登錄不了了。找運維,他們也登錄不了,最后只好重啟了服務器。我分析發現新生代設置的不合適,導致它沒有空間進行full gc。結果內存全滿了。最喜歡做這樣的項目了,用現成的框架,程序會死,把機器弄死很不容易的[偷笑]

  首先說我們線上JVM用的Hotspot,因為是64位機器,只支持server模式的。使用默認的JIT編譯器模式。Java7。因為在java8中移除了永久代,犧牲了一點性能來獲取更高的安全保障。但這個程序是個后台服務,升級java8反而不合適了。

  處理數據對象特別大,有的壓縮前30多M。因為搜索哥哥們規定實時消息一個專輯下要包含所有的視頻,有的專輯下面有幾萬個視頻[哭笑]。所以在處理這一條數據的時候,處理完的部分仍在內存中。為了可維護,晚上全量推送和其他時段的實時推送數據處理部分邏輯共用。晚上全量是用50個線程的線程池來跑的。如果50個線程內部串行,雖然我做了策略,分派處理內容的時候,將超大的專輯獨立出來。一個線程處理幾百個小專輯,但是大專輯只處理兩三個。但是一個專輯就要十幾分鍾。但是專輯的分為多個區域,多種語言的,每種都要獨立成一條數據,全量文件專輯我定義了共440個線程,每個線程獨立壓縮生成一個文件,增量時發消息也是扔到MQ里不用管。這些不需要通信的地方完全可以異步處理。異步又涉及到總是新建線程的堆回收問題。所以我將這些線程類都放到了對象池里進行管理。但是全量的時候的堆占用還是很大很大的,Full GC也很頻繁。空間換時間嘛,所以JVM參數配的看起來很誇張,但真不是浪費。專輯的數據量是十萬級,視頻的數據量是千萬級。原來的離線推送系統只發送ID給搜索那邊,跑全量也要4個小時。所以之前是一周跑一次全量。我做的新系統,全量生成的專輯共15個G,視頻占31個G。專輯和視頻跑完全量一台用20多分鍾,另一台長一些(因為另一台的數據庫的機器不是同一運行商,時間開銷在網路上),現在我們是一天一個全量。

  -Xss這個參數的最終設置,我當時是整晚沒睡覺測試的。因為這個參數是每個線程的堆棧大小。是方法執行的內存區,每個方法執行時會在虛擬機棧中創建棧幀。設置的小,跑起來會慢,設置的大,跑起來快,CPU計算速度就上去了。這里面還涉及到了虛擬機的逃逸分析,可能引起CPU跑滿。說到這里我是不是還得說說虛擬機棧幀的結構啊。

棧幀(Stack Frame)結構

棧幀是用於支持虛擬機進行方法執行的數據結構,是屬性運行時數據區的虛擬機站的棧元素。棧幀包括:

1>局部變量表(locals大小,編譯期確定),一組變量存儲空間,容量以slot為最小單位。

2>操作棧(stack大小,編譯期確定),操作棧元素的數據類型必須與字節碼指令序列嚴格匹配。

3>動態鏈接,指向運行時常量池中該棧幀所屬方法的引用,為了動態連接使用。

  前面是靜態解析

  對於運行期轉化為直接引用,是動態解析

4>方法返回地址。

  正常退出:執行引擎遇到方法返回的字節碼,將返回值傳遞給調用者

  異常退出:遇到Exception沒被捕獲時沒有返回值

5>額外附加信息:由具體虛擬機實現。

說到這里我是不是還應該畫一張java的內存模型啊。大體是這個樣子的:

 

  在這個地方想起來一個習慣,就是我用的集成開發環境是Eclipse,喜歡用它因為它是純java寫的。而且我經常把它搞死。每次把它弄死了我都會很認真的去分析它死掉的原因。對深入了解jvm很有幫助。

 

  有必要貼一下垃圾收集日志。這是線上比較老的GC日志。因為我已經把打印gc日志這個選項關閉很久了。大家可能注意到了我的新生代設置的特別大,37g。這不僅僅是因為測試時服務器掛過。而是我說了,處理的數據對象特別大,這些對象都是朝生暮死的。如果新生代設置的不夠大,這些大對象就會直接進入老年代,大大降低了垃圾回收的效率。大家也可以看出來,對新生代的垃圾回收是相當有成效的,99%都被回收了。

  這里介紹一下數據結構中的棧和堆與內存分配中的棧和堆:

  數據結構中的棧是一種后進先出性質的數據結構,像一個桶。取數據不能像數組那樣想取哪個取哪個。必須先把想取的數據之后進來的數據全pop出去。

  數據結構中的堆通常指二叉堆。分為最大堆和最小堆(我還用這個數據結構實現一種加密機制獲得了專利)。它的存取就要比棧靈活。

  如果是C++出身的程序員對於內存分配的棧和堆理解就完全不是問題。因為java就是c++寫的。內存中的棧區處理相對較高的地址以地址,不斷的分配,分配的地址增大。棧地址是相反的。所以在c++語言中和jvm中,棧都是系統自動分配空間的,速度快。而堆是需要申請的,我記得是malloc函數。棧上的數據的生存周期是在函數的運行過程中,運行后就釋放掉,不可以再訪問。堆上的數據只要程序員不釋放空間,就一直可以訪問到。這就是為什么java棧是線程隔離的,而堆是線程共享的。

如需轉載,請注上我的原文鏈接: http://www.cnblogs.com/xiexj/p/6700747.html  謝謝哦~~


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM