<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          面試官:過期引用你了解嗎?

          共 2817字,需瀏覽 6分鐘

           ·

          2020-08-12 10:39


          學(xué)過JVM的小伙伴一定知道JVM中的四大引用,分別是強(qiáng)引用,軟引用,弱引用,虛引用。今天就來給大家說說什么是過期引用?


          垃圾回收和內(nèi)存分配是JVM的兩大重點,今天通過一個過期引用的小例子串聯(lián)起這兩塊的知識。


          先上代碼


          public?class?Stack?{
          ????private?Object[] elements;
          ????private?int?size = 0;
          ????private?static?final?int?DEFAULT_INITIAL_CAPACITY = 16;

          ????public?Stack()?{
          ????????elements = new?Object[DEFAULT_INITIAL_CAPACITY];
          ????}

          ????public?void?push(Object e)?{
          ????????ensureCapcity();
          ????????elements[size++]=e;
          ????}
          ????public?Object pop(){
          ????????if(size==0){
          ????????????throw??new?EmptyStackException();
          ????????}
          ????????return?elements[--size];
          ????????//Object result=elements[--size];
          ????????//elements[size]=null;
          ????????//return result;
          ????}

          ????private?void?ensureCapcity(){
          ????????if(elements.length==size){
          ????????????elements= Arrays.copyOf(elements,2*size+1);
          ????????}
          ????}
          }


          public?class?JprofilerUserTestMain?{
          ????public?static?void?main(String[] args)?throws InterruptedException {
          ????????//工具測試主類
          ????????Stack stack=new?Stack();
          ????????for?(int?i = 0; i < 1000; i++) {
          ????????????MyClass myClass=new?MyClass(i,""+i,(long)i);
          ????????????stack.push(myClass);
          ????????}
          ????????//等待15s
          ????????Thread.sleep(15000);
          ????????for?(int?i = 0; i < 500; i++) {
          ????????????stack.pop();
          ????????}
          ????????Thread.sleep(1000000);
          ????}
          }


          首先創(chuàng)建了一個棧,棧的內(nèi)部使用使用數(shù)組來實現(xiàn),其中有兩個操作,入棧和出棧,順序入棧,倒置出棧。在Main函數(shù)中 for 循環(huán)先放入1000個元素,15s后 出棧500個元素。


          對于我們來說 對于出棧的元素,我們往往不會再次從棧內(nèi)獲得。所以上面釋放的500個元素 應(yīng)該在之后被垃圾回收,但是通過Jprofiler工具,我發(fā)現(xiàn)在堆中 還是擁有1000個元素。原因是:stack棧中數(shù)組500到1000仍保存著釋放對象的引用,使得500個對象引用成為過期引用。無法被GC 判斷為無用對象進(jìn)行回收。


          如果想要對這些對象進(jìn)行回收 只需要將pop方法中的數(shù)組引用指向為null,在一段時間后系統(tǒng)便會對500個對象進(jìn)行回收。


          總結(jié)一下


          過期引用指的是永遠(yuǎn)不會被解除的引用


          在我們的stack例子中,凡是在elements數(shù)組的”活動范圍“之外的任何引用都是過期的,這里的活動部分指的是elements中下標(biāo)小于size的那些元素。


          過期引用導(dǎo)致的問題


          過期引用會導(dǎo)致內(nèi)存泄漏,內(nèi)存泄露,所謂泄露,就是原來被分配后的內(nèi)存,在失去利用價值后,應(yīng)該還給系統(tǒng)以重復(fù)利用,但卻沒還給系統(tǒng),導(dǎo)致系統(tǒng)可用內(nèi)存越來越少。


          GC如何判斷一個對象是否可以回收,使用兩種方式,一種是引用計數(shù)算法和可達(dá)性分析算法,引用計數(shù)算法 有著引用之間相互嵌套風(fēng)險,所以可達(dá)性分析算法為主要使用,GC root鏈中對象對象可達(dá)則無法被回收,若多個對象和數(shù)組對象 有關(guān),那么垃圾回收機(jī)制不僅不會處理這個對象,而且也不會處理被這個對象所引用的其他對象。即使只有少量幾個對象引用被無意識的保留下來,也會有許許多多的對象被排除在垃圾回收機(jī)制之外。從而對性能造成潛在的巨大影響。


          java源碼中為避免過期引用如何實現(xiàn)


          public?synchronized?E pop()?{
          ????E obj;
          ????int?????len = size();

          ????obj = peek();
          ????removeElementAt(len - 1);

          ????return?obj;
          }


          public?synchronized?void?removeElementAt(int?index)?{
          ????modCount++;
          ????if?(index >= elementCount) {
          ????????throw?new?ArrayIndexOutOfBoundsException(index + " >= "?+
          ?????????????????????????????????????????????????elementCount);
          ????}
          ????else?if?(index < 0) {
          ????????throw?new?ArrayIndexOutOfBoundsException(index);
          ????}
          ????int?j = elementCount - index - 1;
          ????if?(j > 0) {
          ????????System.arraycopy(elementData, index + 1, elementData, index, j);
          ????}
          ????elementCount--;
          ????elementData[elementCount] = null; /* to let gc do its work */
          }


          stack類繼承vector類 ?進(jìn)入vector類中可以看到最后一行代碼,以及它的注釋。


          作者:Deciscive
          鏈接:juejin.im/post/6844904071657160711



          瀏覽 52
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  青青免费在线观看激情视频 | 永久免费看黄网址 | 亚洲免费无吗 | 美女插屄视频 | 91麻豆精品国产91久久久久久 |