部落格

  • 戴姆勒總裁蔡澈:電動汽車續航里程應達499公里以上

    日前,戴姆勒集團總裁迪特•蔡澈(Dieter Zetsche)稱,電動汽車一次充電必須能供應至少310英里(499公里)的行程,才能替代燃油汽車,成為主流。

    但蔡澈在接受美國媒體採訪時稱,在短時期內讓所有消費者接受電動汽車不太可能,並稱這是一個連續的過程。首先要降低車載電池的成本。蔡澈估計該價格在170美元每千瓦時左右,而110-130美元則會使汽車很有競爭優勢。

    本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

    【其他文章推薦】

    USB CONNECTOR掌控什麼技術要點? 帶您認識其相關發展及效能

    ※評比前十大台北網頁設計台北網站設計公司知名案例作品心得分享

    ※智慧手機時代的來臨,RWD網頁設計已成為網頁設計推薦首選

    ※評比南投搬家公司費用收費行情懶人包大公開

  • 長江EV:要做完美的中國智慧電動汽車

    4月17日上午,長江汽車集團董事長曹忠正式發佈了電動汽車品牌“長江EV”,同時,國內規模最大、自動化程度最高、專門生產電動汽車的核心工廠——杭州長江汽車有限公司正式投產,“長江牌”純電動中巴車“奕閣”、純電動商務車 “奕勝”、純電動公車“益眾”和純電動小型SUV“逸酷”,作為首批投產的產品也正式下線。

    六年來,長江汽車進行了向電動汽車發展的全面戰略規劃,建立了完整的系統的電動汽車研發能力,完成了構成電動汽車所有核心零部件的研發和集成,完成了正向開發三個系列電動汽車產品。

    2個研發中心(簡式國際汽車設計(北京)有限公司、上海中聚電池研究院),2個鋰電池生產工廠(天津中聚新能源科技有限公司、吉林中聚新能源科技有限公司),2個整車生產基地(杭州長江汽車有限公司、雲南五龍汽車有限公司)。

    展望未來,從產業和市場的角度來看,傳統汽車和電動車會呈現此消彼長的發展態勢,大體可分為四個階段:

    第一階段是電動汽車占汽車市場的份額約在5%以下。

    第二階段是電動汽車占汽車市場的份額約在5-15%。

    第三階段是電動汽車占汽車市場的份額約在15-30%。

    第四階段是電動汽車在有機融合智慧化的基礎上逐步完美而一躍超過傳統汽車,占汽車市場的份額50%以上。

    此次長江汽車下線儀式暨品牌發佈會上,長江汽車還展示了其車聯網、車載資訊系統的最新科研成果。各系列產品都將智慧終端機和車載資訊服務系統作為標配,實現車與移動智慧設備的無縫對接,滿足人與車、車與路、車與網的資訊交互和解決方案。

     

    本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

    【其他文章推薦】

    台北網頁設計公司這麼多,該如何挑選?? 網頁設計報價省錢懶人包"嚨底家"

    網頁設計公司推薦更多不同的設計風格,搶佔消費者視覺第一線

    ※想知道購買電動車哪裡補助最多?台中電動車補助資訊懶人包彙整

    南投搬家費用,距離,噸數怎麼算?達人教你簡易估價知識!

  • 華爾街日報:蘋果投資滴滴讓Uber面臨前所未有壓力

    《華爾街日報》網站發表文章稱,幾個月前,Uber在拼車服務領域好像是勢不可擋的王者。但最近一系列事件,特別是蘋果向Uber頭號競爭對手投資10億美元,表明形勢已迅速發生變化。此前,Uber在世界各地陷入與監管機構的鬥爭,並努力平息其約100萬位司機隊伍的動盪;如今,它必須面對一家中國初創公司的挑戰,其支持者包括全球最大的電腦製造商、中國最大的互聯網公司和汽車製造巨頭等。

    隨著蘋果的現金注入,中國的打車服務滴滴出行可能獲得蘋果龐大的技術和行銷資源,這將有助於其拓展數以百萬計的新用戶,在快速發展的交通領域開發下一代產品。

    滴滴至少已經獲得50億美元的融資,證明它在資金籌集上可以與Uber的中國業務競爭。滴滴還擁有強大的中國合作夥伴,包括阿裡巴巴集團和騰訊等。在滴滴最近一輪融資中,它們將向該公司投入更多資金。消息人士表示,這輪融資對滴滴的估值為250億美元。滴滴的服務已與阿裡巴巴旗下的支付寶和騰訊的微信進行整合。

    今年年初,Uber最大的美國競爭對手Lyft獲得了通用汽車的支持。通用汽車與Lyft合作,是為了佈局未來無人駕駛汽車領域的競爭。根據雙方合作協定,通用汽車將向Lyft投資5億美元。上周,這兩家公司宣佈,它們計畫明年開始測試無人駕駛電動計程車車隊。在最新一輪融資中,Lyft估值達到了55億美元。

    Uber聯合創始人、CEO 特拉維斯•卡蘭尼克(Travis Kalanick) 習慣諷刺競爭對手。對於蘋果投資其競爭對手的消息,他週五在Twitter上發了一條消息稱,他的女友布持有iPhone製造商的股票,這使她成為他的競爭對手的間接投資人。他在這消息上加上了 “#ridesharewars”和“#thanksalottim” 標籤,指的是蘋果CEO蒂姆•庫克。

    Uber通過債務和股權融資已募集100多億美元資金,最近估值達到625億美元。該公司正在全球範圍內建立合作同盟,從中國百度到印度媒體集團Bennett Coleman & Co都成為其合作夥伴。這些合作夥伴已分別幫助Uber在中國和印度擴張——卡蘭尼克向投資者強調這兩個市場是他的公司最大的擴張機會。

    但在某些方面,Uber喜歡利用其資金來實現其競爭地位,而不是依賴于合作夥伴的幫助。去年,隨著蘋果和Alphabet等財大氣粗的科技巨頭加大對無人駕駛汽車研發的投入,該公司從卡內基•梅隆大學挖來了40位世界頂級機器人技術研究人員和科學家,並在匹茲堡一個新的技術中心啟動了自己的無人駕駛汽車項目。

    Uber與其它公司的合作夥伴關係之一充滿了變數。2013年,Alphabet旗下風投公司Google Ventures向Uber投資了2.5億美元,這是其當時單筆最大投資。但自那以後,穀歌開始測試自己的打車應用,而Uber開始開發自己的地圖和無人駕駛汽車技術,顯然在與穀歌的競爭。不過,Alphabet高級副總裁大衛•德拉蒙德(David Drummond)仍然是Uber的董事會成員。

    Uber採取“自己去做”的策略,與其競爭對手之間不斷擴大合作形成鮮明對比。去年,滴滴向Lyft投資10億美元,如今它們的合作夥伴關係已演變成一個涉及多方的國際聯盟。滴滴和Lyft已將它們的應用捆綁在一起,使中國遊客到美國可以使用Lyft的應用叫車,反之亦然。在未來幾個月內,印度的Ola和新加坡的GrabTaxi Holdings Pte. Ltd計畫推出類似功能。

    Uber在中國市場已處於下風,而蘋果的投資會讓其競爭對手更為強大。為吸引中國拼車服務市場的使用者和投資者,Uber在中國的子公司UberChina與滴滴陷入激烈競爭。滴滴和UberChina都爭相從本地投資者籌集數十億美元的資金,利用現金補貼的舉措爭取司機和乘客使用他們的服務。

    與蘋果的交易可能加強滴滴的技術研發實力。該公司已成立一個名為“滴滴研究院”的研發中心,專注於機器學習、人工智慧和資料採擷等領域。
    文章來源:網易科技

    本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

    【其他文章推薦】

    ※想知道網站建置網站改版該如何進行嗎?將由專業工程師為您規劃客製化網頁設計後台網頁設計

    ※不管是台北網頁設計公司台中網頁設計公司,全省皆有專員為您服務

    ※Google地圖已可更新顯示潭子電動車充電站設置地點!!

    ※帶您來看台北網站建置台北網頁設計,各種案例分享

  • 福特電動休旅車野馬 Mach-E 接近實車照首次曝光

    福特電動休旅車野馬 Mach-E 接近實車照首次曝光

    福特曾表示野馬 Mach-E 將在 2020 秋天開始組裝,但最近在福特墨西哥廠外卻出現一批電動野馬的身影,且看起來像幾乎可以交車了。一起來先睹為快這批電動野馬的實車英姿吧。

    野馬 Mach-E(馬赫 E)是福特首輛純電車,不僅擁有全新心臟,還承繼了傳奇車款野馬的設計靈魂,因此開放預購以來業績奇佳,連一向高傲的特斯拉老闆馬斯克(Elon Musk)都發文恭喜福特,做出一台好車。

    不過第一台電動車製造並沒那麼容易,因此福特將交車日期估得很晚,最快要到 2020 年底才交車,而頂規版的 Mach-E GT 更是要等到 2021 年第一季才會交車。此外,福特也說過,正式生產要到 2020 年秋天才會啟動,請大家不要太著急。

    上週在墨西哥廠外出現的這批 Mach-E 卻讓大家嚇了一跳,因為看起來不僅比之前合成圖帥氣,且幾乎就像已完成組裝,而不是一般原型車或測試車。

    無論原因是什麼,這台 Mach-E 是目前為止最接近實車的照片,這個造型是否打動了你的心?

    今年底將交車的 Mach-E,續航里程預估有 480 公里,並擁有 332 馬力,是目前市場少數能與特斯拉並肩的數據,定價也只有 5 萬美元(台灣售價未定)。

    Mach-E 售價與性能幾乎都衝著特斯拉 Model Y 而來,不過 Model Y 的交車日期可能就在未來兩個月開始,相信所有人(包括福特)都期望 Mach-E 也能提前交車,與 Model Y 一較高下。

    (合作媒體:。圖片來源:)

    本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

    【其他文章推薦】

    網頁設計公司推薦更多不同的設計風格,搶佔消費者視覺第一線

    ※廣告預算用在刀口上,網站設計公司幫您達到更多曝光效益

    ※自行創業 缺乏曝光? 下一步"網站設計"幫您第一時間規劃公司的門面形象

    南投搬家前需注意的眉眉角角,別等搬了再說!

  • 「車和家」產品計畫 中國微信現身

    「車和家」產品計畫 中國微信現身

    4月16日,中國汽車之家創始人李想在微信朋友圈發文表示,目前個人精力110%投入在車和家上,並首次透露具體的產品計畫:車和家將打造兩款車型來滿足90%的城市需求,一款小而美的SEV,一款大而強的SUV。

    3月底,李想的電動車創業項目「車和家」完成A輪融資,並且申報造車資質。李想預計在四年時間裡,打造小而美電動車大概需要2億美元的投入。車和家已經準備好了1億美元,另外的1億美元將通過融資獲得。

    李想強調,車和家不是互聯網造車,也不玩互聯網概念,而是標準的新生代汽車品牌。一是自主研發,研發與製造工程師團隊平均汽車行業從業15年以上;二是自主生產,自建常州武進750畝的30萬產能的全鋁工廠,以及配套的BMS與電池廠;三是自己提供銷售與服務,打破4S店高價、低質、效率低的現狀。車和家的目標是像蘋果一樣去創新產品與商業模式,像華為一樣扎扎實實搞研發,並放眼全球市場。

    以下為李想微信朋友圈全文(簡體中文,截圖):

    本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

    【其他文章推薦】

    ※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!!

    網頁設計一頭霧水??該從何著手呢? 找到專業技術的網頁設計公司,幫您輕鬆架站!

    ※想知道最厲害的台北網頁設計公司推薦台中網頁設計公司推薦專業設計師”嚨底家”!!

  • HashMap7淺析

    HashMap7淺析

    一、概述

      HashMap,基於哈希結構的Map接口的一個實現,無序,允許null鍵值對,線程不安全的。可以使用集合工具類Collections中的synchronizedMap方法,去創建一個線程安全的集合map。

      在jdk1.7中,HashMap主要是基於 數組+鏈表 的結構實現的。鏈表的存在主要是解決 hash 衝突而存在的。插入數據的時候,計算key的hash值,取得存儲的數組下標,如果衝突已有元素,則會在衝突地址上生成個鏈表,再通過key的比較,鏈表是否已存在,存在則覆蓋,不存在則鏈表上添加。這種方式,如果存在大量衝突的時候,會導致鏈表過長,那麼直接導致的就是犧牲了查詢和添加的效率。所以在jdk1.8版本之後,使用的就是 數組 + 鏈表 + 紅黑樹,當鏈表長度超過 8(實際加上初始的節點,整個有效長度是 9) 的時候,轉為紅黑樹存儲。

      本文中內容,主要基於jdk1.7版本,單線程環境下使用的HahsMap沒有啥問題,但是當在多線程下使用的時候,則可能會出現併發異常,具體表象是CPU會直線上升100%。下面是主要介紹相關的存取以及為什麼會出現線程安全性問題。

    二、結構

      

      HashMap默認初始化size=16的哈希數組,然後通過計算待存儲的key的hash值,去計算得到哈希數組的下標值,然後放入鏈表中(新增節點或更新)。鏈表的存在即是解決hash衝突的。

    三、源碼實現分析

      1、存儲具體數據的table數組:

          

        Entry為HashMap中的靜態內部類,其具體結構如下圖

          

        key、value屬性就是存儲鍵值對的,next則是指向鏈表的下一個元素節點。

         2、 默認初始化方法:

        

        默認構造方法,不對table進行初始化new(真正初始化動作放在put中,後面會看到),只是設置參數的默認值,hashmap長度和table長度初始化成DEFAULT_INITIAL_CAPACITY(16),加載因子loadFactor默認DEFAULT_LOAD_FACTOR(0.75f,至於為什麼是0.75,這個可以參見 )。

        加載因子:默認情況下,16*0.75=12,也就是在存儲第13個元素的時候,就會進行擴容(jdk1.7的threshold真正計算放在第一次初始化中,後面會再提及)。此元素的設置,直接影響到的是key的hash衝突問題。

      3、put方法

     public V put(K key, V value) {
       
    if (table == EMPTY_TABLE) { inflateTable(threshold); } if (key == null) return putForNullKey(value); int hash = hash(key); int i = indexFor(hash, table.length); for (Entry<K,V> e = table[i]; e != null; e = e.next) { Object k; if (e.hash == hash && ((k = e.key) == key || key.equals(k))) { V oldValue = e.value; e.value = value; e.recordAccess(this); return oldValue; } } modCount++; addEntry(hash, key, value, i); return null; }

      3.1、EMPTY_TABLE是HashMap中的一個靜態的空的Entry數組,table也是HashMap的一個屬性,默認就是EMPTY_TABLE(這兩句可參見上面源碼),table就是我們真正數據存儲使用的。
      3.2、前面提及,無參構造的時候,並未真正完成對HashMap的初始化new操作,而僅僅只是設置幾個常量,所以在第一次put數據的時候,table是空的。則會進入下面的初始化table方法中。

    if (table == EMPTY_TABLE) {
        inflateTable(threshold);
    }
    
    private void inflateTable(int toSize) {
        // Find a power of 2 >= toSize
        int capacity = roundUpToPowerOf2(toSize);
    
        threshold = (int) Math.min(capacity * loadFactor, MAXIMUM_CAPACITY + 1); //計算加載因子,默認情況下結果為12
        table = new Entry[capacity];  //真正的初始化table數組
        initHashSeedAsNeeded(capacity);
    }

      3.3、key的null判斷

    if (key == null)
        return putForNullKey(value);
    
    private V putForNullKey(V value) {
        for (Entry<K,V> e = table[0]; e != null; e = e.next) {
            if (e.key == null) {
                V oldValue = e.value;
                e.value = value;
                e.recordAccess(this);
                return oldValue;
            }
        }
        modCount++;
        addEntry(0, null, value, 0);
        return null;
    }
    
    void addEntry(int hash, K key, V value, int bucketIndex) {
        if ((size >= threshold) && (null != table[bucketIndex])) {
            resize(2 * table.length);
            hash = (null != key) ? hash(key) : 0;
            bucketIndex = indexFor(hash, table.length);
        }
    
        createEntry(hash, key, value, bucketIndex);
    }
    
    void createEntry(int hash, K key, V value, int bucketIndex) {
        Entry<K,V> e = table[bucketIndex];
        table[bucketIndex] = new Entry<>(hash, key, value, e);
        size++;
    }

      具體步驟解析:

        1、key為null,取出table[0]的鏈表結構Enrty,如果取出的元素不為null,則對其進行循環遍歷,查找其中是否存在key為null的節點元素。

           2、如果存在key == null的節點,則使用新的value去更新節點的oldValue,並且將oldValue返回。

        3、如果不存在key == null的元素,則執行新增元素addEntry方法:

          (1)判斷是否需要擴容,size為當前數組table中,已存放的Entry鏈表個數,更直接點說,就是map.size()方法的返回值。threshold上面的真正初始化HashMap的時候已經提到,默認情況下,計算得到 threshold=12。若同時滿足  (size >= threshold) && (null != table[bucketIndex]) ,則對map進行2倍的擴容,然後對key進行重新計算hash值和新的數組下標。

          (2)創建新的節點原色createEntry方法,首先獲取table數組中下標為bucketIndex的鏈表的表頭元素,然後新建個Entry作為新的表頭,並且新表頭其中的next指向老的表頭數據。

      3.4、key不為null的存儲  
        原理以及過程上通key==null的大體相同,只不過,key==null的時候,固定是獲取table[0]的鏈表進行操作,而在不為key != null的時候,下標位置是通過
      int hash = hash(key); int i = indexFor(hash, table.length); 計算得到的

      static int indexFor(int h, int length) {
            // assert Integer.bitCount(length) == 1 : "length must be a non-zero power of 2";
            return h & (length-1);
        }

      很清晰的就能看明白,先計算key的hash,然後與當前table的長度進行相與,這樣計算得到待存放數據的下標。得到下標后,過程就與key==null一致了,遍歷是否存在,存在則更新並返回oldVlaue,不存在則新建Entry。

      4、get方法

     public V get(Object key) {
            if (key == null)
                return getForNullKey();
            Entry<K,V> entry = getEntry(key);
    
            return null == entry ? null : entry.getValue();
        }
        如果key == null,則調用getForNullKey方法,遍歷table[0]處的鏈表。
    private V getForNullKey() {
            if (size == 0) {
                return null;
            }
            for (Entry<K,V> e = table[0]; e != null; e = e.next) {
                if (e.key == null)
                    return e.value;
            }
            return null;
        }

      如果key != null,則調用getEntry,根據key計算得到在table數組中的下標,獲取鏈表Entry,然後遍歷查找元素,key相等,則返回該節點元素。

     final Entry<K,V> getEntry(Object key) {
            if (size == 0) {
                return null;
            }
    
            int hash = (key == null) ? 0 : hash(key);
            for (Entry<K,V> e = table[indexFor(hash, table.length)];
                 e != null;
                 e = e.next) {
                Object k;
                if (e.hash == hash &&
                    ((k = e.key) == key || (key != null && key.equals(k))))
                    return e;
            }
            return null;
        }

    四、線程不安全分析

      上述,主要淺析了下HashMap的存取過程,HashMap的線程安全性問題主要也就是在上述的擴容resize方法上,下面來看看在高併發下,擴容后,是如何引起100%問題的。

      1、在進行新元素 put 的時候,這在上面中的3.3的代碼片段中可以查看,addEntry 添加新節點的時候,會計算是否需要擴容處理:(size >= threshold) && (null != table[bucketIndex]) 。

      2、如果擴容的話,會接下來調用 resize 方法

     void resize(int newCapacity) {
            Entry[] oldTable = table;
            int oldCapacity = oldTable.length;
            if (oldCapacity == MAXIMUM_CAPACITY) {
                threshold = Integer.MAX_VALUE;
                return;
            }
    
            Entry[] newTable = new Entry[newCapacity];
            //關鍵性代碼,構建新hashmap並將老的數據移動過來
            transfer(newTable, initHashSeedAsNeeded(newCapacity));
            table = newTable;
            threshold = (int)Math.min(newCapacity * loadFactor, MAXIMUM_CAPACITY + 1);
        }

      3、其中,出現100%問題的關鍵就是上面的 transfer 方法,新建hashmap移動複製老數據

     1  void transfer(Entry[] newTable, boolean rehash) {
     2         int newCapacity = newTable.length;
     3         for (Entry<K,V> e : table) {
     4             // 遍歷老的HashMap,當遇到不為空的節點的是,進入移動方法
     5             while(null != e) {
     6                 // 首先創建個Entry節點 指向該節點所在鏈表的下一個節點數據
     7                 Entry<K,V> next = e.next;
     8                 if (rehash) {
     9                     e.hash = null == e.key ? 0 : hash(e.key);
    10                 }
    11               // 計算老的數據在新Hashmap中的下標位置
    12                 int i = indexFor(e.hash, newCapacity);
    13              // 將新HashMap中相應位置的元素,掛載到老數據的後面(不管有無數據)
    14                 e.next = newTable[i];
    15                 // 將新HashMap中相應位置指向上面已經成功掛載新數據的老數據
    16              newTable[i] = e;
    17              // 移動到鏈表節點中的下一個數據,繼續複製節點
    18                 e = next;
    19             }
    20         }
    21     }    

      問題的關鍵就在上述的14、15行上,這兩行的動作,在高併發下可能就會造成循環鏈表,循環鏈表在等待下一個嘗試 get 獲取數據的時候,就悲劇了。下面舉例模擬說說這個過程:

      (1)假設目前某個位置的鏈表存儲結構為 A -> B -> C,有兩個線程同時進行擴容操作

      (2)線程1執行到第7行 Entry<K,V> next = e.next; 的時候被掛起了,此時,線程1的 e 指向 A , next 指向的是 B

      (3)線程2執行完成了整個的擴容過程,那麼此時的鏈表結構應該是變為了 C -> B -> A

      (4)線程1喚醒繼續執行,而需要操作的鏈表實際就變成了了上述線程2完成后的 C ->B -> A,下面分為幾步去完成整個操作:

          第一次循環:

            (i)執行 e.next = newTable[i] ,將 A 的 next 指向線程1的新的HashMap,由於此時無數據,所以 e.next = null

            (ii)執行 newTable[i] = e,將線程1的新的HashMap的第一個元素指向 A 

            (iii)執行e = next,移動到鏈表中的下一個元素,也就是上面的(2)中的 線程掛起的時候的 B

          第二次循環:

            (i)執行 Entry<K,V> next = e.next,此時的 e 指向 B,next指向 A

            (ii)執行 e.next = newTable[i] ,將 B 的 next 指向線程1的新的HashMap,由於此時有數據A,所以 e.next = A

            (iii)執行 newTable[i] = e,將線程1的新的HashMap的第一個元素指向 B,此時線程1的新Hashmap鏈表結構為B -> A

            (iiii)執行e = next,移動到鏈表中的下一個元素 A

          第三次循環:

            (i)執行 Entry<K,V> next = e.next,此時的 e 指向 A,next指向 null

            (ii)執行 e.next = newTable[i] ,將 A 的 next 指向線程1的新的HashMap,由於此時有數據B,所以 e.next = B

            (iii)執行 newTable[i] = e,將線程1的新的HashMap的第一個元素指向 A ,此時線程1的新Hashmap鏈表結構為 A -> B -> A

            (iiii)執行e = next,移動到鏈表中的下一個元素,已移動到鏈表結尾,結束 while 循環,完成鏈表的轉移。

      (5)上述過程中,很顯然的,最終的鏈表結構中,出現了 A -> B -> A 的循環結構。擴容完成了,剩下的等待的是get獲取的時候, getEntry 方法中 for循環e = e.next中就永遠出不來了。

      注意:擴容過程中,newTable是每個擴容線程獨有的,共享的只是每個Entry節點數據,最終的擴容是會調用 table = newTable 賦值操作完成。

    本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理
    【其他文章推薦】

    ※帶您來了解什麼是 USB CONNECTOR  ?

    ※自行創業 缺乏曝光? 下一步"網站設計"幫您第一時間規劃公司的門面形象

    ※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!!

    ※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

    ※廣告預算用在刀口上,網站設計公司幫您達到更多曝光效益

  • 9012年了,再不會Https就老了

    9012年了,再不會Https就老了

    前言  

           合格的web後端程序員,在開發之外,必須給IIS、Nginx、各種原生web服務器上配置Https,不然你就僅僅是個碼農,本博最近將專題記錄

    • 如何為IIS,Nginx配置Https

    • 如何申請適用於生產的免費SSL證書

    本博客小試牛刀,先實操在Nginx for Docker上添加自簽名SSL證書

    為啥先倒騰自簽名SSL證書,申請公網SSL證書需要公網可識別的域名或者公網IP;

    如果有實際SSL證書, 按照本文替換即可。

    手繪Https原理

    長話短說:  目前常見的Http請求明文傳輸, 報文可被截取並篡改,請求可被偽造; 

    因此基於常見HTTP(HTTP-TCP-IP)協議棧引入SSL/TSL(Transport Secure Layer) ,HTTPS在進行加密傳輸之前會進行一次握手,確定傳輸密鑰。

    流程解讀:

    ① 傳輸密鑰是對稱密鑰,用於雙方對傳輸數據的加解密

    ② 怎麼在傳輸之前確立傳輸密鑰呢? 針對普遍的多客戶端訪問受信web服務器的場景, 提出非對稱密鑰(公鑰存於客戶端,私鑰存於web服務器),雙方能互相加解密,說明中間數據(傳輸密鑰)沒被篡改。

    ③ 再拋出疑問,怎麼認定下發的公鑰是這個web服務器匹配的密鑰?怎麼確定這個公鑰下發過程沒被截取篡改? 這就是追溯到握手階段的下發證書過程,瀏覽器內置的CA機構認定該證書是其有效下發,並通過簽名認定該證書沒被篡改,最終認定該 證書下發的公鑰是受信web服務器準確下發。

    ④ 如果面向面試記憶Https原理,恐怕有些難度,所以個人用一種 【雞生蛋還是蛋生雞】的方式向上追溯流程, 方便大家知其然更知其所以然。

    前置準備

     >   CentOS機器上安裝Docker、 Docker-Compose

     >   常規操作構建 Nginx for Docker網站, 項目結構如下: 

    ssl-docker-nginx
        ├── docker-compose.yml
        ├── nginx   
        │      └── nginx.conf
        └── site
               └── index.html

        該項目將會使用  nginx/nginx.conf、site/index.html替換Nginx鏡像默認配置文件和默認啟動頁,docker-compose.yml 如下:

    version: '2'
    services:
      server:
        image: nginx:latest
        volumes:
          - ./nginx/nginx.conf:/etc/nginx/nginx.conf
          - ./site:/usr/share/nginx/html
        ports:
        - "8080:80"

        docker-compose  up -d 啟動Nginx容器,還是那樣熟悉的味道: 【chrome默認將http連接認定為不安全

    添加SSL自簽名證書

    很明顯: web服務器需要存儲證書(內置了公鑰)和私鑰

     ① 創建自簽名證書 (什麼叫自簽名,就是自己給自己頒發 SSL證書)

    [nodotnet@gs-server-5809 ssl-docker-nginx]$ openssl req -newkey rsa:2048 -nodes -keyout nginx/my-site.com.key -x509 -days 365out nginx/my-site.com.crt

    req是證書請求的子命令,-newkey rsa:2048 -keyout nginx/my-site.com.key表示生成私鑰(PKCS8格式),

              -nodes 表示私鑰不加密,

               -x509表示輸出證書,-days365 為有效期,此後根據提示輸入證書擁有者信息;

           之後會在nginx目錄下生產2個文件, 分別是私鑰、證書

     ② 將證書和密鑰掛載到Nginx Image, 修改docker-compose.yml

    version: '2'
    services:
      server:
        image: nginx:latest
        volumes:
          - ./nginx/nginx.conf:/etc/nginx/nginx.conf
          - ./site:/usr/share/nginx/html
          - ./nginx/my-site.com.crt:/etc/nginx/my-site.com.crt    #新行 - ./nginx/my-site.com.key:/etc/nginx/my-site.com.key    #新行
        ports:
        - "8080:80"
        - "443:443"        // 容器開啟HTTPS默認的443端口

     ③  修改nginx/nginx.conf,接受Https請求

    events {
      worker_connections  4096;  ## Default: 1024
    }
    
    http {
        server {
            listen 80;
            root         /usr/share/nginx/html/;
        }
    
        server {            # 新Server接受來自443端口的Https請求
            listen              443 ssl;
            ssl_certificate     /etc/nginx/my-site.com.crt;
            ssl_certificate_key /etc/nginx/my-site.com.key;
            root        /usr/share/nginx/html;
        }
    }

    執行docker-compose down && docker-compose up -d 發起https://10.201.80.126:443請求,當前自簽名證書頒發機構不在瀏覽器內置的CA機構,所以該證書目前被瀏覽器認為是無效。

    理論上將 該自簽名證書導出,之後在 【chrome瀏覽器】-【高級設置】-【管理證書】中導入該證書,即可讓 chrome接受自簽名SSL證書。

    That‘s All,  Https作為以後web的主流配置,碼農進階資深必須掌握;後續會記錄Https & HSTS, 申請免費SSL證書,盡請關注。

     

    本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

    【其他文章推薦】

    ※為什麼 USB CONNECTOR 是電子產業重要的元件?

    網頁設計一頭霧水??該從何著手呢? 找到專業技術的網頁設計公司,幫您輕鬆架站!

    ※想要讓你的商品成為最夯、最多人討論的話題?網頁設計公司讓你強力曝光

    ※想知道最厲害的台北網頁設計公司推薦台中網頁設計公司推薦專業設計師”嚨底家”!!

  • 如何高效的學習技術

    如何高效的學習技術

      我們相信努力學習一定會有收穫,但是方法不當,既讓人身心疲憊,也沒有切實的回報。高中時代,我的同桌是個漂亮女同學。她的物理成績很差,雖然她非常勤奮的學習,但成績總是不理想。為了鞏固純潔的同學關係,我親密無間地輔導她的物理,發現她不知道題目考什麼。我們的教科書與試題都圍繞着考試大綱展開,看到一道題,應該先想想它在考哪些定理和公式的運用。
      不少朋友每天都閱讀技術文章,但是第二天就忘乾淨了。工作中領導和同事都認可你的溝通和技術能力,但是跳槽面試卻屢屢碰壁。面試官問技術方案,明明心裏清楚,用嘴說出來卻前言不搭后語。面試官再問底層算法,你說看過但是忘記了。他不在乎你看沒看過,答不上就是零分。正如男女相親,男方談吐瀟洒才能吸引姑娘。可是男方緊張了,平時挺能說,關鍵時候卻支支吾吾,姑娘必然認為他不行。人生充滿了許多考試,有形的和無形的,每次考試的機會只有一次。
      工作五年十年後,別人成了架構師,自己還在基層打滾,原因是什麼?職場上無法成功升遷的原因有很多,沒有持續學習、學習效果不好、無法通過心儀公司的的面試,一定是很重要的原因。
      把自己當成一台計算機,既有輸入,也要有輸出,用輸出倒逼輸入

      近些年誕生了許多新技術,比如最時髦的AI(目前還在智障階段),數學基礎是初中就接觸過的概率統計。萬丈高樓從地起,不要被新工具或者中間件迷住雙眼,一味地追新求快。基礎知識是所有技術的基石,在未來很長的時間都不會變化,應該花費足夠的時間鞏固基礎。
      以數據結構和算法為例,大家閱讀一下Java的BitSet的源碼,裏面有大量的移位操作,移位運算掌握的好,看這份源碼就沒問題。Java同步工具類AQS用到了雙向鏈表,鏈表知識不過關,肯定搞不懂它的原理。互聯網大廠都喜歡考算法,為了通過面試也要精通算法。
      以Java工程師應該掌握的知識為例,按重要程度排出六個梯度:

    • 第一梯度:計算機組成原理、數據結構和算法、網絡通信原理、操作系統原理;
    • 第二梯度:Java基礎、JVM內存模型和GC算法、JVM性能調優、JDK工具、設計模式;
    • 第三梯度:Spring系列、Mybatis、Dubbo等主流框架的運用和原理;
    • 第四梯度:MySQL(含SQL編程)、Redis、RabbitMQ/RocketMQ/Kafka、ZooKeeper等數據庫或者中間件的運用和原理;
    • 第五梯度:CAP理論、BASE理論、Paxos和Raft算法等其他分佈式理論;
    • 第六梯度:容器化、大數據、AI、區塊鏈等等前沿技術理論;

    有同學認為第五梯度應該在移到第一梯度。其實很多小公司的日活犹如古天樂一樣平平無奇,離大型分佈式架構還遠得很。學習框架和中間件的時候,順手掌握分佈式理論,效果更好。

      許多公司的招聘JD沒有設定技術人員年齡門檻,但是會加上一句“具備與年齡相當的知識的廣度與深度”。多廣才算廣,多深才算深?這是很主觀的話題,這裏不展開討論。
      如何變得更廣更深呢?突破收入上升的瓶頸,發掘自己真正的興趣
      大多數人只是公司的普通職員,收入上升的瓶頸就是升職加薪。許多IT公司會對技術人員有個評級,如果你的評級不高,那就依照晉級章程努力升級。如果你在一個小公司,收入一般,發展前景不明,準備大廠的面試就是最好的學習過程。在這些過程中,你必然學習更多知識,變得更廣更深。
      個人興趣是前進的動力之一,許多知名開源項目都源於作者的興趣。個人興趣並不局限技術領域,可以是其他學科。我有個朋友喜歡玩山地自行車,還給一些做自行車話題的自媒體投稿。久而久之,居然能夠寫一手好文章了,我相信他也能寫好技術文檔。

      哲學不是故作高深的學科,它的現實意義就是解決問題。年輕小伙是怎麼泡妞的?三天兩頭花不斷,大庭廣眾跪求愛。這類套路為什麼總是能成功呢?禮物滿足女人的物慾,當眾求愛滿足女人的虛榮心,投其所好。食堂大媽打菜的手越來越抖,辣子雞丁變成辣子辣丁,為什麼呢?食堂要控製成本,直接提價會惹眾怒。
      科學上的哲學,一般指研究事物發展的規律,歸納終極的解決方案。軟件行業充滿哲學味道的作品非常多,比如。舉個例子,當軟件系統遇到性能問題,嘗試下面兩種哲學思想提升性能:

    • 空間換時間:比如引入緩存,消耗額外的存儲提高響應速度。
    • 時間換空間:比如大文件的分片處理,分段處理后再匯總結果。

    設計穩健高可用的系統,嘗試從三個方面考慮問題:

    • 存儲:數據會丟失嗎,數據一致性怎麼解決。
    • 計算:計算怎麼擴容,應用允許任意增加節點嗎。
    • 傳輸:網絡中斷或擁塞怎麼辦。

    從無數的失敗或者成功的經驗中,總結出高度概括性的方案,讓我們下一步做的更好。

      英語是極為重要的基礎,學好英語與掌握編程語言一樣重要。且不說外企對英語的要求,許多知名博客就是把英文翻譯成中文,充當知識的搬運工。如果英語足夠好,直接閱讀一手英語資料,避免他人翻譯存在的謬誤。

      體系化的知識比零散的更容易記憶和理解,這正如一部好的電視劇,劇情環環相扣才能吸引觀眾。建議大家使用思維導圖羅列知識點,構建體繫結構,如下圖所示:

      高中是我們知識的巔峰時刻,每周小考每月大考,教輔資料堆成山,地獄式的反覆操練強化記憶。複習是對抗遺忘的唯一辦法。大腦的遺忘是有規律的,先快后慢。一天後,學到的知識只剩下原來的25%,甚至更低。隨着時間的推移,遺忘的速度減慢,遺忘的數量也就減少。

    時間間隔 記憶量
    剛看完 100%
    20分鐘后 60%
    1小時后 40%
    1天後 30%
    2天後 27%

    每個人的遺忘程度都不一樣,建議第二天複習前一天的內容,七天後複習這段時間的所有內容。

      不少朋友利用碎片時間學習,比如在公交上看公眾號的推送。其實我們都高估了自己的抗干擾能力,如果處在嘈雜的環境,注意力容易被打斷,記憶留存度也很低。碎片時間適合學習簡單孤立的知識點,比如鏈表的定義與實現。
      學習複雜的知識,需要大段的連續時間。圖書館是個好地方,安靜氛圍好。手機放一邊,不要理會QQ微信,最好閱讀紙質書,泡上一整天。有些城市出現了付費自習室,提供格子間、茶水等等,也是非常好的選擇。

      從下面這張圖我們可以看到,教授他人是知識留存率最高的方式。

      準備PPT和演講內容,給同事來一場技術分享。不光複習知識,還鍛煉口才。曾經有個同事說話又快又急,口頭禪也多,比如”對吧、是不是”,別人經常聽不清,但是他本人不以為然。領導讓他做了幾次技術分享,聽眾的反應可想而知,他才徹底認清缺點。
      堅持寫技術博客,別在意你寫的東西在網上已經重複千百遍。當自己動手的時候,才會意識到眼高手低。讓文章讀起來流暢清晰,需要嘔心瀝血的刪改。寫作是對大腦的長期考驗,想不到肯定寫不出,想不清楚肯定寫不清楚。

    我們經常說不要重複造輪子。為了開發效率,可以不造輪子,但是必須具備造輪子的能力。建議造一個簡單的MQ,你能用到通信協議、設計模式、隊列等許多知識。在造輪子的過程中,你會頻繁的翻閱各種手冊或者博客,這就是用輸出倒逼輸入

    本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

    【其他文章推薦】

    USB CONNECTOR掌控什麼技術要點? 帶您認識其相關發展及效能

    ※評比前十大台北網頁設計台北網站設計公司知名案例作品心得分享

    ※智慧手機時代的來臨,RWD網頁設計已成為網頁設計推薦首選

    ※評比南投搬家公司費用收費行情懶人包大公開

  • 計算機硬件—調度與死鎖

    計算機硬件—調度與死鎖

    進程調度原因及調度切換時機,進程調度方式與實現及各種調度算法的個人總結:

    1.一般調度概念 1)什麼是調度 就是選出待分派的作業或進程。 操作系統管理了系統的有限資源,當有多個進程(或作業)發出請求要使用這些資源時,因為資源的有限性,必須按照一定的原則選擇進程(或作業)來佔用資源。這就是調度。

    2)調度目的 1.控制資源使用者的數量 2.選取資源使用者 3.許可哪些使用者佔用資源 4.讓使用者直接佔用資源。

    二、調度類型 1、高級調度(長程調度)。 即作業調度,選取輸入井中的作業,生成根進程。目的是控制使用系統資源的進程數。

    2、中級調度(中程調度)。 指選取進程佔用內存或有資格佔用內存,又稱進程滾入滾出,中級調度將在存儲管理章節中介紹,有頁式調度、段式調度、段頁式調度等。

    3、低級調度(短程調度) 指選取進程佔用處理機,又稱進程調度。 4、I/O調度 選取進程佔用I/O設備。

    三、調度和狀態轉換 在許多系統中,調度被分為三種:長程、中程和短程。 1)調度和進程狀態轉換

     

    從狀態轉換的觀點: 1、長程調度(作業調度)就是將一個或一批作業從後備狀態變為運行狀態。一個作業一旦被高級調度選中,便可獲得所需要的基本內存和設備資源,並被裝入內存,此後就以進程形式參与併發執行,與其它進程競爭CPU。

    從狀態轉換的觀點: 2、中程調度就是將進程從活動態變為靜止的掛起態,或者將進程從掛起態變為就緒或阻塞態。 3、短程調度就是將某個進程從就緒態變為(在CPU上運行的)執行態。

    2)調度的層次(調度作用的嵌套關係)

     

     

     

    3)三級調度示意圖 調度從根本上講,是要使隊列延遲的時間最小,並優化系統的執行效率

     

     

     

     

     

     

     

    4.1.2作業調度的功能

    ①記錄系統中各個作業的情況。 ②按照某種調度算法從後備作業隊列中挑選作業,即決定接納多少個作業進入內存和挑選哪些作業進入內存。

    ③為選中的作業分配內存和外設等資源。 ④為選中的作業建立相應的進程,並把該進程放入就緒隊列中。 ⑤作業結束後進行善後處理工作。如輸出必要的信息,收回該作業所佔用的全部資源,撤消與該作業相關的全部進程和該作業的JCB 。

     

    4.1.3進程調度的功能與調度時機 一、進程調度的功能 (1)保存現場(2)挑選進程(3)恢復現場

     

     

     

    二、進程調度的時機 一般在下列事件發生后要執行進程調度。 (1)創建進程。 當進程創建時,要決定是運行父進程還是子進程。 (2)進程終止。 (3)等待事件。 (4)中斷髮生。 (5)運行到時。

    4.1.4進程調度的基本方式 1)非剝奪調度(非搶佔) 只有當處理機上的進程主動放棄處理機時,才重新調度。 2)剝奪調度(搶佔) 當進程運行時可以被系統以某種原則為由剝奪其處理機。

    例:只有一部電話機,小李正在通電話,此時小張有急事也要打電話,此時小張的調度方式有兩種: 一種是非搶佔,即等待小李打完電話,自己再打電話。 另一種是搶佔,不等小李通完電話,搶過話筒就撥打電話。

    3)進程調度在核心態進行。 CPU狀態有兩種,目態和管態。 管態——也稱核心態或系統態,系統程序在CPU上運行的狀態。 目態——用戶程序在CPU上運行的狀態。

     

     

     

    4.2 調度算法 4.2.1 常用的調度算法

    1. FCFS 誰先到就緒隊列就將處理機分給誰。 2. 短作業優先 取一個下次所需運行時間最短的作業(該算法能使平均等待時間最短)。

    3. 優先級調度 選優先級最高的進程佔用處理機(優先級可動態改變)。 4.輪轉調度法 以先來後到的次序+ 時間片輪轉。

    5.多隊列調度法 按屬性將就緒進程分類,不同類進程可有不同的調度算法。 6.多級反饋隊列調度法 設置多條就緒隊列,進程被調度執行后,在被剝奪或放棄處理機后而在就緒時,可以改變其就緒隊列(見下圖)。

     

     

    又一個多級反饋隊列調度算法的例子:使用優先權實現調度。做法如下:

    (1)以優先級設置多隊列。 (2)各隊列的調度算法採用FCFS+時間片輪轉. (3)進程優先級升降原則是:等待過久升,輸入/輸出完成時升,運行完一個完整時間片降……

    (4)進程最初進入就緒隊列以用戶初置優先級為參數。 (5)開始調度時,先從最高優先權的就緒隊列(RQ0)開始選取一個進程,如果RQ0空,則檢查RQ1,如此下去。見下圖示:

     

     

    4.2.2 調度策略的討論

    一、調度性能評價準則 1、CPU利用率。 2、吞吐率。即每單位時間所完成的作業數目。 3、周轉時間。即從作業提交直至完成這一作業的時間間隔。

    4、等待時間。即作業在就緒隊列中等待所花的時間。 5、響應時間。即從作業提交到首次產生回答信息之間的時間。

    二、主要的調度算法 下面以表所示的進程集作為範例討論不同的調度策略。 到達時間:進程或作業提交時間。 服務時間:進程要求服務的時間,或完成作業所需的時間。

     

    一、FCFS調度策略(或先進先出)

     

     

     

     

     

     

     

    FCFS策略更適合於長進程。例:

     

     

    注:周轉時間=完成時間—到達時間 tq/ts :帶權周轉時間=周轉時間/服務時間

    (1)進程C的等待標準化時間是不能容忍的。它位於系統的總時間是它所需服務時間的100倍。無論何時,一個長進程到后,一個短進程就會出現較長的等待。 (2)進程D的標準化等待時間尚可容忍,小於2.0。進程D的輪轉時間差不多是C的兩倍。

    總結: FCFS(First Come First Served)即先來先服務,故它的本質是非搶佔的。它簡單易行,但調度性能較差,有可能使短的、重要的或緊迫的作業等進程長期等待,其實現過程容易,可採用FIFO隊列管理。

    本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

    【其他文章推薦】

    台北網頁設計公司這麼多,該如何挑選?? 網頁設計報價省錢懶人包"嚨底家"

    網頁設計公司推薦更多不同的設計風格,搶佔消費者視覺第一線

    ※想知道購買電動車哪裡補助最多?台中電動車補助資訊懶人包彙整

    南投搬家費用,距離,噸數怎麼算?達人教你簡易估價知識!

  • Java性能分析神器–VisualVM Launcher[1]

    Java性能分析神器–VisualVM Launcher[1]

    Java性能分析神器1–VisualVM Launcher

    VisualVM

    當你日復一日敲代碼的時候,當你把各種各樣的框架集成到一起的時候,看着大功告成成功運行的日誌,有沒有那麼一絲絲迷茫和惆悵:這TM起的是什麼玩意?每一行日誌背後代表的是什麼東西??他為什麼就能跑起來了呢????

    這種時候不要慌,給大家推薦一款功能強大的插件:VisualVM Launcher。(eclipse就叫 )。這個插件需要和客戶端配合使用 。

    VisualVM是集成了命令行JDK工具和輕量級分析功能的可視化工具。JVM提供了一些常用的jdk命令行工具:

    • jstat(JVM Statistics Monitoring Tool):用於收集Hotspot虛擬機各方面的運行數據(查看虛擬機各雲心狀態信息),显示本地或遠程虛擬機進程中的類裝載,內存,垃圾收集, JIT編譯等運行數據。
    • jps(JVM Process Status Tool):显示指定系統內所有的HotSpot虛擬機進程(查看虛擬機進程信息),可用於查詢正在運行的虛擬機進程, 同時可選擇性的显示虛擬機執行主類, 即執行main函數的類, 以及進程的本地虛擬機
      ID(Local Virtual Machine Identifier 簡稱LVMID)(對於本地虛擬機進程來說, 進程的本地虛擬機ID與操作系統的進程ID是一致的)
    • jinfo(Configuration Info for Java):显示虛擬機配置信息(查看虛擬機配置參數信息),可用於查看和調整虛擬機的配置參數.
    • jmap(JVM Memory Map):生成虛擬機的內存轉儲快照, 生成heapdump文件(生成虛擬機內存轉儲快照),可用於獲取heapdump文件, 且可以查詢finalize執行隊列, Java堆與永久代的一些信息。
    • jhat(JVM Heap Dump Browser):用於分析heapdump文件, 它會建立一個HTTP/HTML服務器, 讓用戶在瀏覽器上查看分析結果(分析虛擬機轉儲快照信息),jhat命令與jmap命令搭配使用, 用於分析jmap生成的堆轉儲快照, jhat內置了一個微型的HTTP/HTML服務器, 生成dump文件的分析結果后, 可以在瀏覽器中查看。
    • jstack(JVM Stack Trace):显示虛擬機的線程快照(虛擬機堆棧跟蹤),用於生成虛擬機當前時刻的線程快照。 線程快照指的是當前虛擬機內的每一條線程正在執行的方法堆棧的集合, 生成線程快照的作用是, 可用於定位線程出現長時間停頓的原因, 如線程間死鎖, 死循環, 請求外部資源導致的長時間等待等問題, 當線程出現停頓時 就可以用jstack各個線程調用的堆棧情況

    這些工具功能強大,可以很方便的查看jvm內存分配,內存大小,裝載類總數,線程總數等。有了這些信息,就可以很快的進程診斷,性能調優辣。

    安裝VisualVM和VisualVM Launcher

    1. Idea安裝VisualVM Launcher插件

    ​ Preferences –> Plugins –> 搜索VisualVM Launcher,安裝重啟即可

    2. 配置Idea VisualVM Launcher插件

    ​ Preferences –> other settings -> VisualVM Launcher –> 輸入VisualVM executable 和 JDK home即可

    3. 配置完之後的idea頁面

    4. 安裝VisualVM客戶端

    ​ –> 選擇對應的系統安裝包 –> 對應安裝,安裝完成后打開是這樣的頁面:

    VisualVM和java命令行工具

    1. jmap+jhat內存快照與分析:Heap Dump
    1. HeapDump又叫做堆存儲文件,指一個Java進程在某個時間點的內存快照。Heap Dump在觸發內存快照的時候會保存此刻的java對象和類的信息。通常在寫heap Dump文件前會觸發一次FullGC,所以heap dump文件里保存的都是FullCG后留下的對象信息。

    2. jmap進行內存快照方式:

      jmap -dump:format=b,file=<filename.hprof> <pid>

    3. jhat進行內存快照分析:

      • jhat <heap dump file>
      • 使用了jhat命令,就啟動了一個http服務,端口是7000,即http://localhost:7000/,就可以在瀏覽器里分析
    4. VisualVM進行內存快照方式:

      • 在“應用程序”窗口中右鍵單擊應用程序節點,然後選擇“堆 Dump”。
      • 在“應用程序”窗口中雙擊應用程序節點以打開應用程序標籤,然後在“監視”標籤中單擊“堆 Dump”。
    5. VisualVM快照頁面,也可以右鍵保存此時的快照:

    6. 想要打開保存好的java快照:

      • 單擊“堆 Dump”工具欄中的“類”,以查看活動類和對應實例的列表。
      • 雙擊某個類名打開“實例”視圖,以查看實例列表。
      • 從列表中選擇某個實例,以查看對該實例的引用。
    2. jinfo:显示虛擬機配置信息(查看虛擬機配置參數信息)
    1. 虛擬機配置信息:JVM的啟動參數

    2. jinfo進行查看虛擬機配置信息查詢(jinfo -help查看更多)

      jinfo <pid>

    3. Visual VM查看虛擬機配置信息,直接在應用程序打開,就可以看到JVM參數 和 系統屬性:

    4. 一些常見的虛擬機配置參數:

      • -Xms:初始堆大小。如:-Xms256m
      • -Xmx:最大堆大小。如:-Xmx512m
      • -Xmn:新生代大小。通常為 Xmx 的 1/3 或 1/4。
      • -Xss:為每個線程分配的內存大小,JDK1.5+ 每個線程堆棧大小為 1M,一般來說如果棧不是很深的話, 1M 是絕對夠用了的。
      • -XX:NewRatio:新生代與老年代的比例,如 –XX:NewRatio=2,則新生代占整個堆空間的1/3,老年代佔2/3
      • -XX:SurvivorRatio:新生代中 Eden 與 Survivor 的比值。默認值為 8。即 Eden 佔新生代空間的 8/10,另外兩個 Survivor 各占 1/10
      • -XX:PermSize:永久代(方法區)的初始大小
        • PermSize永久代的概念在jdk1.8中已經不存在了,取而代之的是metaspace元空間,當認為執行永久代的初始大小以及最大值是jvm會給出如此下提示:
          • Java HotSpot(TM) 64-Bit Server VM warning: ignoring option PermSize=30m; support was removed in 8.0
          • Java HotSpot(TM) 64-Bit Server VM warning: ignoring option MaxPermSize=30m; support was removed in 8.0
      • -XX:MaxPermSize:永久代(方法區)的最大值
      • -XX:+PrintGCDetails:打印 GC 信息
      • -XX:+HeapDumpOnOutOfMemoryError:讓虛擬機在發生內存溢出時 Dump 出當前的內存堆轉儲快照,以便分析用
    3. jps查看虛擬機進程信息
    1. 用來查詢正在運行的虛擬機進程

    2. jps命令,:

      • jps
    3. VisualVM查看正在運行的虛擬機進程:

    4. jstack显示虛擬機的線程快照
    1. 生成虛擬機當前時刻的線程快照,用來查找運行時死鎖,死循環的原因

    2. jstack命令,

      • jstack <pid>
    3. VisualVM生成虛擬機線程快照方式:

      • 在“應用程序”窗口中右鍵單擊應用程序節點,然後選擇“線程 Dump”。
      • 在“應用程序”窗口中雙擊應用程序節點以打開應用程序標籤,然後在“線程”標籤中單擊“線程 Dump”。
    4. VisualVM線程快照頁面,也可以右鍵保存快照:

    5. jstat收集Hotspot虛擬機各方面的運行數據
    1. 運行數據:對Java應用程序的資源和性能進行實時監控,主要包括GC情況和Heap Size資源使用情況。

    2. jstat進行資源與性能監控,:

      • jstat -gc <pid>
    3. VisualVM進行程序資源的實時監控:

    VisualVM也提供了一些其他功能

    此外,VisualVM也提供很多插件,有各樣的功能,我就不多介紹了

    這篇文章,介紹了VisualVM的作用和用法,下面會寫一篇姊妹篇 帶上代碼,去分析當系統出現死鎖或者循環等異常時,內存、線程和CPU在做什麼。

    本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

    【其他文章推薦】

    ※想知道網站建置網站改版該如何進行嗎?將由專業工程師為您規劃客製化網頁設計後台網頁設計

    ※不管是台北網頁設計公司台中網頁設計公司,全省皆有專員為您服務

    ※Google地圖已可更新顯示潭子電動車充電站設置地點!!

    ※帶您來看台北網站建置台北網頁設計,各種案例分享