国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

內(nèi)存溢出、內(nèi)存泄露的概述及常見情形

這篇具有很好參考價值的文章主要介紹了內(nèi)存溢出、內(nèi)存泄露的概述及常見情形。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

內(nèi)存溢出(OutofMemoryError)

簡述

java doc 中對 Out Of Memory Error 的解釋是,沒有空閑內(nèi)存,并且垃圾收集器也無法提供更多內(nèi)存。

JVM 提供的內(nèi)存管理機(jī)制和自動垃圾回收極大的解放了用戶對于內(nèi)存的管理,由于 GC(垃圾回收)一直在發(fā)展,所有一般情況下,除非應(yīng)用程序占用的內(nèi)存增長速度非???,造成垃圾回收已經(jīng)跟不上內(nèi)存消耗的速度,否則不太容易出現(xiàn)內(nèi)存泄漏和內(nèi)存溢出問題。但是基本不會出現(xiàn)并不等于不會出現(xiàn),所以掌握 Java 內(nèi)存模型原理和學(xué)會分析出現(xiàn)的內(nèi)存溢出或內(nèi)存泄漏仍然十分重要。

大多數(shù)情況下,GC 會進(jìn)行各種年齡段的垃圾回收,實在不行了就放大招,來一次獨占式的 Full GC 操作,這時候會回收大量的內(nèi)存,供應(yīng)用程序繼續(xù)使用。

在拋出 OutofMemoryError 之前,通常垃圾收集器會被觸發(fā),盡其所能去清理出空間。例如:在引用機(jī)制分析中,涉及到 JVM 會去嘗試回收軟引用指向的對象等。在 java.nio.BIts.reserveMemory() 方法中,System.gc() 會被調(diào)用,以清理空間。

當(dāng)然,也不是在任何情況下垃圾收集器都會被觸發(fā)的。比如,分配了一個超大對象,類似一個超大數(shù)組超過堆的最大值,JVM 可以判斷出垃圾收集并不能解決這個問題,所以直接拋出 OutofMemoryError。


內(nèi)存溢出的常見情形

不同的內(nèi)存溢出錯誤可能會發(fā)生在內(nèi)存模型的不同區(qū)域,因此,需要根據(jù)出現(xiàn)錯誤的代碼具體分析來找出可能導(dǎo)致錯誤發(fā)生的地方,并想辦法進(jìn)行解決。

  • 棧內(nèi)存溢出(StackOverflowError)

    棧內(nèi)存可以分為虛擬機(jī)棧(VM Stack)和本地方法棧(Native Method Stack),除了它們分別用于執(zhí)行 Java 方法(字節(jié)碼)和本地方法,其余部分原理是類似的。

    以虛擬機(jī)棧為例說明,Java 虛擬機(jī)棧是線程私有的,當(dāng)線程中方法被調(diào)度時,虛擬機(jī)會創(chuàng)建用于保存局部變量表、操作數(shù)棧、動態(tài)連接和方法出口等信息的棧幀(Stack Frame)。

    具體來說,當(dāng)線程執(zhí)行某個方法時,JVM 會創(chuàng)建棧幀并壓棧,此時剛壓棧的棧幀就成為了當(dāng)前棧幀。如果該方法進(jìn)行遞歸調(diào)用時,JVM 每次都會將保存了當(dāng)前方法數(shù)據(jù)的棧幀壓棧,每次棧幀中的數(shù)據(jù)都是對當(dāng)前方法數(shù)據(jù)的一份拷貝。如果遞歸的次數(shù)足夠多,多到棧中棧幀所使用的內(nèi)存超出了棧內(nèi)存的最大容量,此時 JVM 就會拋出 StackOverflowError。

    總之,不論是因為棧幀太大還是棧內(nèi)存太小,當(dāng)新的棧幀內(nèi)存無法被分配時,JVM 就會拋出 StackOverFlowError。

    優(yōu)化方案:

    • 可以通過設(shè)置 JVM 啟動參數(shù) -Xss 參數(shù)來改變棧內(nèi)存大小。

      注:分配給棧的內(nèi)存并不是越大越好,因為棧內(nèi)存越大,線程多,留給堆的空間就不多了,容易拋出OOM。JVM的默認(rèn)參數(shù)一般情況沒有問題(包括遞歸)。

    • 遞歸調(diào)用要控制好遞歸的層級,不要太高,超過棧的深度。

    • 遞歸調(diào)用要防止形成死循環(huán),否則就會出現(xiàn)棧內(nèi)存溢出。

  • 堆內(nèi)存溢出(OutOfMemoryError:java heap space)

    堆內(nèi)存的唯一作用就是存放數(shù)組和對象實例,即通過 new 指令創(chuàng)建的對象,包括數(shù)組和引用類型。

    堆內(nèi)存溢出又分為兩種情況:

    • Java 虛擬機(jī)的堆內(nèi)存設(shè)置不夠

      如果堆的大小不合理(沒有顯式指定 JVM 堆大小或者指定數(shù)值偏小),對象所需內(nèi)存太大,創(chuàng)建對象時分配空間,JVM 就會拋出 OutOfMemoryError:java heap space 異常。

      優(yōu)化方案:

      • 如果要處理比較可觀的數(shù)據(jù)量,可以通過修改 JVM 啟動參數(shù) -Xms 、-Xmx 來調(diào)整。使用壓力測試來調(diào)整這兩個參數(shù)達(dá)到最優(yōu)值。

      • 盡量避免大的對象的申請,例如文件上傳,大批量從數(shù)據(jù)庫中獲取等。

        盡量分塊或者分批處理,有助于系統(tǒng)的正常穩(wěn)定的執(zhí)行。

      • 盡量提高一次請求的執(zhí)行速度,垃圾回收越早越好。

        否則,大量的并發(fā)來了的時候,再來新的請求就無法分配內(nèi)存了,就容易造成系統(tǒng)的雪崩。

    • 堆內(nèi)存泄露最終導(dǎo)致堆內(nèi)存溢出

      當(dāng)堆中一些對象不再被引用但垃圾回收器無法識別時,這些未使用的對象就會在堆內(nèi)存空間中無限期存在,不斷的堆積就會造成內(nèi)存泄漏。不停的堆積最終會觸發(fā) java . lang.OutOfMemoryError。

      優(yōu)化方案:如果發(fā)生了內(nèi)存泄漏,則可以先找出導(dǎo)致泄漏發(fā)生的對象是如何被 GC ROOT 引用起來的,然后通過分析引用鏈找到發(fā)生泄漏的地方,進(jìn)行代碼優(yōu)化。

  • 永久代溢出(OutOfMemoryError:PermGen sapce)

    對于老版本的 oracle JDK,因為永久代的大小是有限的,并且 JVM 對永久代垃圾回收(例如常量池回收、卸載不再需要的類型)非常不積極,所以當(dāng)不斷添加新類型的時候,永久代出現(xiàn) OutOfMemoryError 也非常多見,尤其是在運行時存在大量動態(tài)類型生成的場合;類似 intern 字符串緩存占用太多空間,也會導(dǎo)致 OOM 問題,對應(yīng)的異常信息,會標(biāo)記出來和永久代相關(guān):“java.lang.OutOfMemoryError:PermGen space"。

    隨著元數(shù)據(jù)區(qū)的引入,方法區(qū)內(nèi)存已經(jīng)不再那么窘迫,所以相應(yīng)的 OOM 有所改觀,出現(xiàn) OOM,異常信息則變成了:“java.lang.OutofMemoryError:Metaspace"。

  • 元空間內(nèi)存溢出(OutOfMemoryError: Metaspace)

    元空間的溢出,系統(tǒng)會拋出 java.lang.OutOfMemoryError: Metaspace

    出現(xiàn)這個異常的問題的原因是系統(tǒng)的代碼非常多或引用的第三方包非常多或者通過動態(tài)代碼生成類加載等方法,導(dǎo)致元空間的內(nèi)存占用很大。

    優(yōu)化方案:

    • 默認(rèn)情況下,元空間的大小僅受本地內(nèi)存限制。

      但是為了整機(jī)的性能,盡量還是要對該項進(jìn)行設(shè)置,優(yōu)化參數(shù)配置,以免造成整機(jī)的服務(wù)停機(jī)。

    • 慎重引用第三方包

      對第三方包,一定要慎重選擇,不需要的包就去掉。

      這樣既有助于提高編譯打包的速度,也有助于提高遠(yuǎn)程部署的速度。

    • 關(guān)注動態(tài)生成類的框架

      對于使用大量動態(tài)生成類的框架,要做好壓力測試,驗證動態(tài)生成的類是否超出內(nèi)存的需求會拋出異常。

  • 直接內(nèi)存溢出

    如果直接或間接(很多 java NIO,例如在 netty 的框架中被封裝為其他的方法)使用了 ByteBuffer 中的 allocateDirect() 方法,而又不做 clear 的時候,就會拋出 java.lang.OutOfMemoryError: Direct buffer memory 異常。

    如果經(jīng)常有類似的操作,可以考慮設(shè)置 JVM 參數(shù):-XX:MaxDirectMemorySize,并及時 clear 內(nèi)存。

  • 創(chuàng)建本地線程內(nèi)存溢出

    除了堆以外的區(qū)域,無法為線程分配一塊內(nèi)存區(qū)域了(線程基本只占用堆以外的內(nèi)存區(qū)域),要么是內(nèi)存本身就不夠,要么堆的空間設(shè)置得太大了,導(dǎo)致了剩余的內(nèi)存已經(jīng)不多了,而由于線程本身要占用內(nèi)存,所以就不夠用了。

    優(yōu)化方案:

    • 首先檢查操作系統(tǒng)是否有線程數(shù)的限制,如果使用 shell 也無法創(chuàng)建線程,就需要調(diào)整系統(tǒng)的最大可支持的文件數(shù)。
    • 日常開發(fā)中盡量保證線程最大數(shù)的可控制的,不要隨意使用可以無限制增長的線程池。
  • 數(shù)組超限內(nèi)存溢出

    JVM 在為數(shù)組分配內(nèi)存之前,會執(zhí)行特定平臺的檢查:分配的數(shù)據(jù)結(jié)構(gòu)是否在此平臺是可尋址的。

    一般來說 java 對應(yīng)用程序所能分配數(shù)組最大大小是有限制的,只不過不同的平臺限制有所不同,但通常在1到21億個元素之間。當(dāng)應(yīng)用程序試圖分配大于 Java 虛擬機(jī)可以支持的數(shù)組時會報 Requested array size exceeds VM limit 錯誤。

    不過這個錯誤一般少見的,主要是由于 Java 數(shù)組的索引是 int 類型。 Java 中的最大正整數(shù)為 2 ^ 31 - 1 = 2,147,483,647。 并且平臺特定的限制可以非常接近這個數(shù)字,例如:Jdk1.8 可以初始化數(shù)組的長度高達(dá) 2,147,483,645(Integer.MAX_VALUE-2)。若是在將數(shù)組的長度再增加 1 達(dá)到 nteger.MAX_VALUE-1 ,就會出現(xiàn) OutOfMemoryError 了。

    優(yōu)化方案:數(shù)組長度要在平臺允許的長度范圍之內(nèi)。

  • 超出交換區(qū)內(nèi)存溢出

    在 Java 應(yīng)用程序啟動過程中,可以通過 -Xmx 和其他類似的啟動參數(shù)限制指定的所需的內(nèi)存。而當(dāng) JVM 所請求的總內(nèi)存大于可用物理內(nèi)存的情況下,操作系統(tǒng)開始將內(nèi)容從內(nèi)存轉(zhuǎn)換為硬盤。

    當(dāng)應(yīng)用程序向 JVM native heap 請求分配內(nèi)存失敗并且 native heap 也即將耗盡時, JVM 會拋出Out of swap space 錯誤, 錯誤消息中包含分配失敗的大?。ㄒ宰止?jié)為單位)和請求失敗的原因。

    優(yōu)化方案:

    • 增加系統(tǒng)交換區(qū)的大小。

      但如果使用了交換區(qū),性能會大大降低,不建議采用這種方式。

      生產(chǎn)環(huán)境盡量避免最大內(nèi)存超過系統(tǒng)的物理內(nèi)存。其次,去掉系統(tǒng)交換區(qū),只使用系統(tǒng)的內(nèi)存,保證應(yīng)用的性能。

  • 系統(tǒng)殺死進(jìn)程內(nèi)存溢出

    操作系統(tǒng)是建立在進(jìn)程的概念之上,這些進(jìn)程在內(nèi)核中作業(yè),其中有一個非常特殊的進(jìn)程,稱為“內(nèi)存殺手(Out of memory killer)”。當(dāng)內(nèi)核檢測到系統(tǒng)內(nèi)存不足時,OOM killer 被激活,檢查當(dāng)前誰占用內(nèi)存最多然后將該進(jìn)程殺掉。

    一般 Out of memory:Kill process or sacrifice child 報錯會在當(dāng)可用虛擬內(nèi)存(包括交換空間)消耗到讓整個操作系統(tǒng)面臨風(fēng)險內(nèi)存不足時,會被觸發(fā)。在這種情況下,OOM Killer 會選擇“流氓進(jìn)程”并殺死它。

    優(yōu)化方案:

    • 增加交換空間的方式可以緩解 Java heap space 異常
    • 但還是建議最好的方案就是升級系統(tǒng)內(nèi)存,讓 java 應(yīng)用有足夠的內(nèi)存可用,就不會出現(xiàn)這種問題。

內(nèi)存泄漏(memory leak)

簡述

  • 也稱作“存儲滲漏”。

  • 嚴(yán)格來說,只有對象不會再被程序用到了,但是 GC 又不能回收它們的情況,才叫內(nèi)存泄漏。

    但實際情況很多時候一些不太好的實踐(或疏忽)會導(dǎo)致對象的生命周期變得很長甚至導(dǎo)致 OOM,也可以叫做寬泛意義上的“內(nèi)存泄漏”。

  • 盡管內(nèi)存泄漏并不會立刻引起程序崩潰,但是一旦發(fā)生內(nèi)存泄漏,程序中的可用內(nèi)存就會被逐步蠶食,直至耗盡所有內(nèi)存,最終出現(xiàn) OutOfMemory 異常,導(dǎo)致程序崩潰。

    注意:這里的可用內(nèi)存并不是指物理內(nèi)存,而是指虛擬內(nèi)存大小,這個虛擬內(nèi)存大小取決于磁盤交換區(qū)設(shè)定的大小。

  • Java 使用可達(dá)性分析算法,最上面的數(shù)據(jù)不可達(dá),就是需要被回收的。

    后期有一些對象不用了,按道理應(yīng)該斷開引用,但是存在一些鏈沒有斷開,從而導(dǎo)致沒有辦法被回收


可達(dá)性分析算法

可達(dá)性分析算法:判斷對象是否是不再使用的對象,本質(zhì)都是判斷一個對象是否還被引用。那么對于這種情況下,由于代碼的實現(xiàn)不同就會出現(xiàn)很多種內(nèi)存泄漏問題(讓 JVM 誤以為此對象還在引用中,無法回收,造成內(nèi)存泄漏)。

舉例說明:

  • 對象 X 引用對象 Y,X 的生命周期比 Y 的生命周期長;
  • 那么當(dāng) Y 生命周期結(jié)束的時候,X 依然引用著 Y,這時候,垃圾回收期是不會回收對象 Y 的;
  • 如果對象 X 還引用著生命周期比較短的 A、B、C,對象 A 又引用著對象 a、b、c,這樣就可能造成大量無用的對象不能被回收,進(jìn)而占據(jù)了內(nèi)存資源,造成內(nèi)存泄漏,直到內(nèi)存溢出。

內(nèi)存泄漏與內(nèi)存溢出的表現(xiàn),# Java基礎(chǔ),jvm,java,面試,內(nèi)存泄露,內(nèi)存溢出


Java 中內(nèi)存泄漏的 8 種情況

  1. 靜態(tài)集合類,如 HashMap、LinkedList 等等。

    如果這些容器為靜態(tài)的,那么它們的生命周期與 JVM 程序一致,則容器中的對象在程序結(jié)束之前將不能被釋放,從而造成內(nèi)存泄漏。

    簡而言之,長生命周期的對象持有短生命周期對象的引用,盡管短生命周期的對象不再使用,但是因為長生命周期對象持有它的引用而導(dǎo)致不能被回收。

  2. 單例模式

    單例模式,和靜態(tài)集合導(dǎo)致內(nèi)存泄露的原因類似,因為單例的靜態(tài)特性,它的生命周期和 JVM 的生命周期一樣長,所以如果單例對象如果持有外部對象的引用,那么這個外部對象也不會被回收,那么就會造成內(nèi)存泄漏。

  3. 內(nèi)部類持有外部類的引用

    在 Java 中內(nèi)部類的定義與使用一般為成員內(nèi)部類與匿名內(nèi)部類,他們的對象都會隱式持有外部類對象的引用,影響外部類對象的回收。

    可以通過反編譯可以來驗證這個理論:

    • java 代碼

      public class Outer {
          private String name;
          class Inner{
              private String test;
          }
      }
      
    • 反編譯后的代碼

      class Outer$Inner {
          private String test;
          final Outer this$0;
          Outer$Inner() {
              this.this$0 = Outer.this;
              super();
          }
      }
      

      可以清楚的發(fā)現(xiàn),內(nèi)部類的屬性中有這個外部類,并且在內(nèi)部類的構(gòu)造函數(shù)中有這個外部類屬性的初始化。

    如果一個外部類的實例對象的方法返回了一個內(nèi)部類的實例對象,而這個內(nèi)部類對象被長期引用了,那么即使那個外部類實例對象不再被使用,但由于內(nèi)部類持有外部類的實例對象引用,這個外部類對象將不會被垃圾回收,這也會造成內(nèi)存泄漏。

  4. 各種連接,如數(shù)據(jù)庫連接、網(wǎng)絡(luò)連接和 IO 連接等

    在對數(shù)據(jù)庫進(jìn)行操作的過程中,首先需要建立與數(shù)據(jù)庫的連接,當(dāng)不再使用時,需要調(diào)用 close 方法來釋放與數(shù)據(jù)庫的連接。只有連接被關(guān)閉后,垃圾回收器才會回收對應(yīng)的對象。

    否則,如果在訪問數(shù)據(jù)庫的過程中,**對 Connection、Statement 或 ResultSet 不顯性地關(guān)閉,將會造成大量的對象無法被回收,**從而引起內(nèi)存泄漏。

  5. 變量不合理的作用域

    一般而言,一個變量的定義的作用范圍大于其使用范圍,很有可能會造成內(nèi)存泄漏。另一方面,如果沒有及時地把對象設(shè)置為 null,很有可能導(dǎo)致內(nèi)存泄漏的發(fā)生。

    public class UsingRandom {
      private String msg;
      public void receiveMsg(){
         //private String msg;
         readFromNet(); // 從網(wǎng)絡(luò)中接受數(shù)據(jù)保存到msg中
         saveDB(); // 把msg保存到數(shù)據(jù)庫中
         //msg = null;
      }
    }
    

    如上面這個偽代碼,通過 readFromNet 方法把接受的消息保存在變量 msg 中,然后調(diào)用 saveDB 方法把 msg 的內(nèi)容保存到數(shù)據(jù)庫中,此時 msg 已經(jīng)就沒用了,由于 msg 的生命周期與對象的生命周期相同,此時 msg 還不能回收,因此造成了內(nèi)存泄漏。

    優(yōu)化方案:

    • 方案1:這個 msg 變量可以放在方法內(nèi)部,當(dāng)方法使用完,那么 msg 的生命周期也就結(jié)束,就可以回收了。
    • 方案2:在使用完 msg 后,把 msg 設(shè)置為 null,這樣垃圾回收器也會回收 msg 的內(nèi)存空間。
  6. 改變哈希值

    當(dāng)一個對象被存儲進(jìn) HashSet 集合中以后,就不能修改這個對象中的那些參與計算哈希值的字段了。

    否則,對象修改后的哈希值與最初存儲進(jìn) HashSet 集合中時的哈希值就不同了,在這種情況下,即使在 contains 方法使用該對象的當(dāng)前引用作為的參數(shù)去 HashSet 集合中檢索對象,也將返回找不到對象的結(jié)果,這也會導(dǎo)致無法從 HashSet 集合中單獨刪除當(dāng)前對象,造成內(nèi)存泄漏。

    這也是 String 為什么被設(shè)置成了不可變類型,可以放心地把 String 存入 HashSet,或者把 String 當(dāng)做 HashMap 的 key 值;

    當(dāng)想把自己定義的類保存到散列表的時候,需要保證對象的 hashCode 不可變。

    /**
     * 演示內(nèi)存泄漏
     */
    public class ChangeHashCode1 {
        public static void main(String[] args) {
            HashSet hs = new HashSet();
            Point cc = new Point();
            cc.setX(10);//hashCode = 41
            hs.add(cc);
            cc.setX(20);//hashCode = 51
            System.out.println("hs.remove = " + hs.remove(cc));//false
            hs.add(cc);
            System.out.println("hs.size = " + hs.size());//size = 2
        }
    }
    
    class Point {
        int x;
    
        public int getX() return x;
        public void setX(int x) this.x = x;
    
        @Override
        public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result + x;
            return result;
        }
    
        @Override
        public boolean equals(Object obj) {
            if (this == obj) return true;
            if (obj == null) return false;
            if (getClass() != obj.getClass()) return false;
            Point other = (Point) obj;
            if (x != other.x) return false;
            return true;
        }
    }
    
  7. 對象緩存泄漏

    一旦把對象引用放入到緩存中,就很容易遺忘。

    比如:代碼中會加載一個表中的數(shù)據(jù)到緩存(內(nèi)存)中,測試環(huán)境只有幾百條數(shù)據(jù),但是生產(chǎn)環(huán)境則可能會有幾百萬的數(shù)據(jù)。

    優(yōu)化方案:可以使用 WeakHashMap 代表緩存,此種 Map 的特點是,當(dāng)除了自身有對 key 的引用外,此 key 沒有其他引用那么此 map 會自動丟棄此值。

    /**
     * 演示內(nèi)存泄漏
     */
    public class MapTest {
        static Map wMap = new WeakHashMap();
        static Map map = new HashMap();
    
        public static void main(String[] args) {
            init();
            testWeakHashMap();
            testHashMap();
        }
    
        public static void init() {
            String ref1 = new String("obejct1");
            String ref2 = new String("obejct2");
            String ref3 = new String("obejct3");
            String ref4 = new String("obejct4");
            wMap.put(ref1, "cacheObject1");
            wMap.put(ref2, "cacheObject2");
            map.put(ref3, "cacheObject3");
            map.put(ref4, "cacheObject4");
            System.out.println("String引用ref1,ref2,ref3,ref4 消失");
    
        }
    
        public static void testWeakHashMap() {
    
            System.out.println("WeakHashMap GC之前");
            for (Object o : wMap.entrySet()) {
                System.out.println(o);
            }
            try {
                System.gc();
                TimeUnit.SECONDS.sleep(5);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("WeakHashMap GC之后");
            for (Object o : wMap.entrySet()) {
                System.out.println(o);
            }
        }
    
        public static void testHashMap() {
            System.out.println("HashMap GC之前");
            for (Object o : map.entrySet()) {
                System.out.println(o);
            }
            try {
                System.gc();
                TimeUnit.SECONDS.sleep(5);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("HashMap GC之后");
            for (Object o : map.entrySet()) {
                System.out.println(o);
            }
        }
    
    }
    /**
     * 結(jié)果
     * String引用ref1,ref2,ref3,ref4 消失
     * WeakHashMap GC之前
     * obejct2=cacheObject2
     * obejct1=cacheObject1
     * WeakHashMap GC之后
     * HashMap GC之前
     * obejct4=cacheObject4
     * obejct3=cacheObject3
     * Disconnected from the target VM, address: '127.0.0.1:51628', transport: 'socket'
     * HashMap GC之后
     * obejct4=cacheObject4
     * obejct3=cacheObject3
     **/
    

    上面代碼演示 WeakHashMap 如何自動釋放緩存對象:當(dāng) init 函數(shù)執(zhí)行完成后,局部變量字符串引用 weakd1,weakd2,d1,d2 都會消失,此時只有靜態(tài) map 中保存中對字符串對象的引用,可以看到,調(diào)用 gc 之后,HashMap 的沒有被回收,而 WeakHashMap 里面的緩存被回收了。

  8. 監(jiān)聽器和回調(diào)

    內(nèi)存泄漏另一個常見來源是監(jiān)聽器和其他回調(diào),如果客戶端在實現(xiàn)的 API 中注冊回調(diào),卻沒有顯式的取消,那么就會積聚。

    需要確?;卣{(diào)立即被當(dāng)作垃圾回收的最佳方法是只保存它的弱引用,例如將它們保存成為 WeakHashMap 中的鍵。文章來源地址http://www.zghlxwxcb.cn/news/detail-812590.html

到了這里,關(guān)于內(nèi)存溢出、內(nèi)存泄露的概述及常見情形的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • 性能優(yōu)化-內(nèi)存泄漏、內(nèi)存溢出、cpu占用高、死鎖、棧溢出詳解

    性能優(yōu)化-內(nèi)存泄漏、內(nèi)存溢出、cpu占用高、死鎖、棧溢出詳解

    含義:內(nèi)層泄露是程序中己動態(tài)分配的堆內(nèi)存由于某種原因程序未釋放或無法釋放,造成系統(tǒng)內(nèi)存的浪費。(換言之,GC回收不了這些不再被使用的對象,這些對象的生命周期太長) 危害:當(dāng)應(yīng)用程序長時間連續(xù)運行時,會導(dǎo)致嚴(yán)重的性能下降;OOM;偶爾會耗盡連接對象;可

    2024年01月19日
    瀏覽(26)
  • 什么是內(nèi)存溢出?什么是內(nèi)存泄露?

    什么是內(nèi)存溢出?什么是內(nèi)存泄露?

    文章目錄 一、什么是內(nèi)存溢出? ?二、什么是內(nèi)存泄露? 三、如何避免內(nèi)存溢出和內(nèi)存泄露? 一、什么是內(nèi)存溢出? ????????假設(shè)我們JVM中可用的內(nèi)存空間只有 3M ,但是我們要創(chuàng)建一個 5M 的對象,那么新創(chuàng)建的對象就放不進(jìn)去了。這個時候,我們就叫做內(nèi)存溢出。就好

    2024年02月08日
    瀏覽(22)
  • 前端內(nèi)存泄漏和溢出的情況以及解決辦法

    前端內(nèi)存泄漏和溢出的情況以及解決辦法

    在平時寫代碼時,內(nèi)存泄漏的情況會時有發(fā)生,雖然js有內(nèi)存回收機(jī)制,但在平時編程中還是需要注意避免內(nèi)存泄漏的情況;前幾天做移動端時遇到一個內(nèi)存泄漏造成移動端頁面卡頓的問題,所以想總結(jié)下前端內(nèi)存泄漏的情況,回顧下基礎(chǔ)知識 ?程序運行時操作系統(tǒng)會分配相

    2024年01月19日
    瀏覽(44)
  • 使用asan檢測內(nèi)存泄漏、堆棧溢出等問題

    操作過程參考:鏈接 緣起:程序在移動端崩潰,mac端復(fù)現(xiàn)不了,于是在寫個崩潰位置函數(shù)的調(diào)用demo,使用ASAN工具進(jìn)行排查。 驗證過程 1、代碼 main.cpp 使用附加ASAN工具的方式進(jìn)行編譯: 執(zhí)行: 沒有問題,以上是驗證過程,如有問題執(zhí)行時ASAN會提示有問題的相關(guān)位置。 介紹

    2024年02月11日
    瀏覽(28)
  • jvm內(nèi)存溢出排查(使用idea自帶的內(nèi)存泄漏分析工具)

    jvm內(nèi)存溢出排查(使用idea自帶的內(nèi)存泄漏分析工具)

    想分析堆內(nèi)存溢出,一定在運行jar包時就寫上參數(shù) -XX:+HeapDumpOnOutOfMemoryError ,可以看我之前關(guān)于如何運行jar包的文章。若你沒有寫??梢詫懮蠀?shù),重啟你的項目,等你的項目發(fā)生下一次堆內(nèi)存溢出異常,在運行的同級文件夾,將產(chǎn)生類似這樣一個文件 java_pid74935.hprof ,若你

    2024年02月09日
    瀏覽(30)
  • Android TextView動態(tài)地加載資源文件,避免Native 層內(nèi)存泄漏或內(nèi)存溢出

    在 Android 中,如果使用 TextView 的 setBackgroundResource() 方法設(shè)置背景,可能會導(dǎo)致 Native 層內(nèi)存增長。這是因為 setBackgroundResource() 方法會將資源文件(例如圖片)加載到內(nèi)存中,如果頻繁地調(diào)用該方法,就會導(dǎo)致內(nèi)存泄漏或內(nèi)存溢出。 為了避免這種問題,可以使用 TextView 的 s

    2024年02月09日
    瀏覽(22)
  • 常見的內(nèi)存泄漏原因和解決方案

    1.全局引用 問題:在JavaScript代碼中,使用全局變量或全局對象來保存對DOM元素或其他對象的引用,這可能導(dǎo)致內(nèi)存泄漏。 解決方案:避免使用全局變量或全局對象,改用合適的作用域來管理變量和對象的生命周期。確保在不再需要時正確地釋放這些引用。 2.事件監(jiān)聽器 問題

    2024年02月13日
    瀏覽(36)
  • SWIFT中最常見的內(nèi)存泄漏陷阱

    如果您有內(nèi)存循環(huán),它將在調(diào)試器中向您顯示警告: 如果確實有一個(或通常是一堆),則表示您有一個泄漏的物體。 您如何預(yù)防呢? 就像在關(guān)閉的第一行中添加 [unowned self] 一樣簡單! 而已! 它將阻止泄漏。 之所以會發(fā)生內(nèi)存泄漏,是因為Swift中的閉包必須捕獲作用域(

    2024年02月07日
    瀏覽(19)
  • 【Go】常見的四個內(nèi)存泄漏問題

    1、這里更多的是由于channel+for+select導(dǎo)致的,錯誤的寫法導(dǎo)致了發(fā)送者或接收者沒有發(fā)現(xiàn)channel已經(jīng)關(guān)閉,任務(wù)已經(jīng)結(jié)束了,卻仍然在嘗試輸入輸出https://geektutu.com/post/hpg-exit-goroutine.html 不要把map用作全局

    2024年02月13日
    瀏覽(28)
  • 常見內(nèi)存溢出與CPU 100%問題

    SQL in 過多 https://mp.weixin.qq.com/s/g5Y47cQ25KbVjzHhZcjN7g 面對 OOM 問題如果代碼不是有明顯的問題,下面幾個JVM參數(shù)相當(dāng)有用,尤其是在容器化之后。 另外提一個參數(shù)也很有用,正常來說如果程序出現(xiàn) OOM 之后,就是有代碼存在內(nèi)存泄漏的風(fēng)險,這個時候即使能對外提供服務(wù),其實也

    2024年02月01日
    瀏覽(13)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包