最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

七段小代碼解決Java程序常見的崩潰場景

 更新時間:2022年06月14日 11:12:15   作者:小姐姐味道  
這篇文章主要為大家介紹了七段小代碼解決Java程序常見的崩潰場景,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

前言

Java程序是基于GC的,在啟動初始,就申請了足量的內(nèi)存池,再加上JIT等編譯器的實時優(yōu)化,速度并不比直接用C++語言寫的慢。Java語言同時由于反射和可觀測等特點,再加上JFR這種神器,在發(fā)生問題的時候比二進制文件更容易找到它的根源。

最近在看RCA(Root Cause Analysis)的東西,不小心發(fā)現(xiàn)了yCrash這么個東西。它的幾段問題小代碼寫的非常典型,我們可以稍微看一下,來看看Java應(yīng)用程序常見的幾個崩潰場景。

1.堆空間溢出

OOM 一般是內(nèi)存泄漏引起的,表現(xiàn)在 GC 日志里,一般情況下就是 GC 的時間變長了,而且每次回收的效果都非常一般。GC 后,堆內(nèi)存的實際占用呈上升趨勢。

下面的代碼是死循環(huán),持續(xù)向HashMap里塞數(shù)據(jù),由于myMap屬于GCRoots,始終得不到釋放,所以它最終的結(jié)果就是OOM。

import java.util.HashMap;
public class OOMDemo {
   static HashMap<Object, Object> myMap = new HashMap<>();
   public static void start() throws Exception { 
      while (true) {
         myMap.put("key" + counter, "Large stringgggggggggggggggggggggggggggg"
               + "ggggggggggggggggggggggggggggggggggggggggggggggggggggg" 
               + "ggggggggggggggggggggggggggggggggggggggggggggggggggggg" 
               + "ggggggggggggggggggggggggggggggggggggggggggggggggggggg" 
               + "ggggggggggggggggggggggggggggggggggggggggggggggggggggg" 
               + "ggggggggggggggggggggggggggggggggggggggggggggggggggggg" 
               + "ggggggggggggggggggggggggggggggggggggggggggggggggggggg" 
               + "ggggggggggggggggggggggggggggggggggggggggggggggggggggg" 
               + "ggggggggggggggggggggggggggggggggggggggggggggggggggggg" 
               + "ggggggggggggggggggggggggggggggggggggggggggggggggggggg" 
               + "ggggggggggggggggggggggggggggggggggggggggggggggggggggg" 
               + "ggggggggggggggggggggggggggggggggggggggggggggggggggggg" 
               + counter);         
         ++counter;
      }
   }   
}

2.內(nèi)存泄漏

內(nèi)存泄漏和內(nèi)存溢出是一個道理,不同的是它的語意。

內(nèi)存溢出可能是由于請求量過高,或者真實的業(yè)務(wù)需求需要所造成的后果,而內(nèi)存溢出屬于未知的、超出期望的OOM情況。

我們可以使用上面同樣的代碼達到這個目的。

在現(xiàn)實情況中,內(nèi)存泄漏通常都非常的隱蔽,需要借助Mat等工具才能找到根本原因。jmap、pmap等是常用的工具。

比如,如果你忘記了重寫對象的hashCode和equals方法,就會產(chǎn)生內(nèi)存泄漏。

//leak example : created by xjjdog 2022
import java.util.HashMap;
import java.util.Map;
public class HashMapLeakDemo {
    public static class Key {
        String title;
        public Key(String title) {
            this.title = title;
        }
    }
    public static void main(String[] args) {
        Map<Key, Integer> map = new HashMap<>();
        map.put(new Key("1"), 1);
        map.put(new Key("2"), 2);
        map.put(new Key("3"), 2);
        Integer integer = map.get(new Key("2"));
        System.out.println(integer);
    }
}

3.CPU飆升

直接一個死循環(huán),就可以把CPU干死。

public class CPUSpikeDemo {
  public static void start() {
    new CPUSpikerThread().start();
    new CPUSpikerThread().start();
    new CPUSpikerThread().start();
    new CPUSpikerThread().start();
    new CPUSpikerThread().start();
    new CPUSpikerThread().start();
    System.out.println("6 threads launched!");
  }
}
public class CPUSpikerThread extends Thread {
  @Override
  public void run() {
    while (true) {
      // Just looping infinitely
    }
  }
}

獲取問題代碼通??梢允褂孟旅娴姆椒ā?/p>

  • (1)使用 top 命令,查找到使用 CPU 最多的某個進程,記錄它的 pid。使用 Shift + P 快捷鍵可以按 CPU 的使用率進行排序。
  • (2)再次使用 top 命令,加 -H 參數(shù),查看某個進程中使用 CPU 最多的某個線程,記錄線程的 ID。
  • (3)使用 printf 函數(shù),將十進制的 tid 轉(zhuǎn)化成十六進制。
  • (4)使用 jstack 命令,查看 Java 進程的線程棧。
  • (5)使用 less 命令查看生成的文件,并查找剛才轉(zhuǎn)化的十六進制 tid,找到發(fā)生問題的線程上下文。

4.線程泄漏

線程資源是昂貴的。如果你不停的創(chuàng)建線程,系統(tǒng)資源很快就會被耗盡。下面的代碼一直不停的創(chuàng)建線程,如果同時請求壓力比較大的話,多數(shù)能搞死宿主機。

public class ThreadLeakDemo {
   public static void start() {
      while (true) {
         new ForeverThread().start();
      }
   }
}
public class ForeverThread extends Thread {
   @Override
   public void run() {
      // Put the thread to sleep forever, so they don't die.
      while (true) {
         try {
            // Sleeping for 10 minutes repeatedly
            Thread.sleep(10 * 60 * 1000);
         } catch (Exception e) {}
      }
   }
}

這是暴力啊,這和每個請求創(chuàng)建一個線程,或者創(chuàng)建一個線程池的后果是一樣的。xjjdog這里還有兩篇關(guān)聯(lián)的線程泄漏文章。

強烈反對使用Spring封裝的多線程類!

奪命故障!炸出了投資人!

java.lang.OutOfMemoryError: unable to create new native thread

5.死鎖

死鎖代碼一般不會發(fā)生,但一旦發(fā)生還是非常嚴(yán)重的,相關(guān)的業(yè)務(wù)可能就跑不動了。

public class DeadLockDemo {
   public static void start() {
      new ThreadA().start();
      new ThreadB().start();
   }
}
public class ThreadA extends Thread {
    @Override 
    public void run() {
        CoolObject.method1();
    }
}
public class ThreadB extends Thread {
    @Override 
     public void run() {
          HotObject.method2();
     } 
}
public class CoolObject {
    public static synchronized void method1() {
       try {
     // Sleep for 10 seconds
     Thread.sleep(10 * 1000);
          } catch (Exception e) {}
          HotObject.method2();
     }
}
public class HotObject {
   public static synchronized void method2() {
       try {
          // Sleep for 10 seconds
          Thread.sleep(10 * 1000);
       } catch (Exception e) {}
       CoolObject.method1();
   } 
}

死鎖屬于比較嚴(yán)重的一種情況,jstack 會以明顯的信息進行提示。當(dāng)然,關(guān)于線程的 dump,也有一些線上分析工具可以使用。比如fastthread,但也需要你先了解這些情況發(fā)生的意義。

6.棧溢出

棧溢出不會造成 JVM 進程死亡,危害“相對較小”。下面是一個簡單的模擬棧溢出的代碼,只需要遞歸調(diào)用就可以了。

public class StackOverflowDemo {
   public void start() {
      start();
   }
}

通過 -Xss 參數(shù)可以設(shè)置虛擬機棧的大小。比如下面的命令就是設(shè)置棧大小為 128K。

-Xss128K

如果你的應(yīng)用經(jīng)常發(fā)生這種情況,可以試著調(diào)大這個值。但一般都是因為程序錯誤引起的,最好檢查一下自己的代碼。

7.Blocked線程

BLOCKED是一個比較嚴(yán)重的線程狀態(tài),當(dāng)后端的服務(wù)處理時間非常長,請求的線程就會進入等待狀態(tài)。這時候通過jstack來獲取堆棧,就會發(fā)現(xiàn)線程處于阻塞狀態(tài)。它阻塞在對鎖的獲取上(wating to lock)

public class BlockedAppDemo {
   public static void start() {
      for (int counter = 0; counter < 10; ++counter) {
      // Launch 10 threads.
      new AppThread().start();
      }
   }
}
public class AppThread extends Thread {
   @Override
   public void run() {
      AppObject.getSomething();
   }
}
public class AppObject {
   public static synchronized void getSomething() {
      while (true) {
         try {
         Thread.sleep(10 * 60 * 1000);
  } catch (Exception e) {}
      }
  }
}

一旦頻繁發(fā)生這種情況,就證明你的程序相應(yīng)太慢了。如果CPU資源還有剩余,可以嘗試著增加請求的線程數(shù),比如tomcat的最大線程數(shù)。

End

以上就是對于Java常見故障的幾段小代碼分析,大部分的故障都逃不出這些場景。故障的排查通常都非常耗費精力,而且你得有線上權(quán)限。怎樣做一些好用的工具,把這些復(fù)雜性屏蔽在后面,才是我們所想要的,更多關(guān)于Java程序崩潰解決代碼的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Java多線程 ReentrantLock互斥鎖詳解

    Java多線程 ReentrantLock互斥鎖詳解

    這篇文章主要介紹了Java多線程 ReentrantLock互斥鎖詳解,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-09-09
  • Java程序包裝成桌面應(yīng)用程序方式

    Java程序包裝成桌面應(yīng)用程序方式

    這篇文章主要介紹了Java程序包裝成桌面應(yīng)用程序方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-01-01
  • java使用JDBC動態(tài)創(chuàng)建數(shù)據(jù)表及SQL預(yù)處理的方法

    java使用JDBC動態(tài)創(chuàng)建數(shù)據(jù)表及SQL預(yù)處理的方法

    這篇文章主要介紹了java使用JDBC動態(tài)創(chuàng)建數(shù)據(jù)表及SQL預(yù)處理的方法,涉及JDBC操作數(shù)據(jù)庫的連接、創(chuàng)建表、添加數(shù)據(jù)、查詢等相關(guān)實現(xiàn)技巧,需要的朋友可以參考下
    2017-08-08
  • Java中callable的實現(xiàn)原理

    Java中callable的實現(xiàn)原理

    本文主要介紹了Java里的callable的實現(xiàn)原理,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-03-03
  • spring boot國際化之MessageSource的使用方法

    spring boot國際化之MessageSource的使用方法

    這篇文章主要給大家介紹了spring boot國際化之MessageSource使用的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11
  • JVM?jstack實戰(zhàn)之死鎖問題詳解

    JVM?jstack實戰(zhàn)之死鎖問題詳解

    如果在生產(chǎn)環(huán)境發(fā)生了死鎖,我們將看到的是部署的程序沒有任何反應(yīng)了,這個時候我們可以借助?jstack進行分析,下面我們實戰(zhàn)操作查找死鎖的原因
    2022-10-10
  • 解決springboot無法注入JpaRepository的問題

    解決springboot無法注入JpaRepository的問題

    這篇文章主要介紹了解決springboot無法注入JpaRepository的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-01-01
  • Springdoc替換swagger的實現(xiàn)步驟分解

    Springdoc替換swagger的實現(xiàn)步驟分解

    最近在spring看到的,spring要對api文檔動手了,有些人說swagger不好用,其實也沒那么不好用,有人說代碼還是有點侵入性,這倒是真的,我剛試了springdoc可以說還是有侵入性但是也可以沒有侵入性,這就看你對文檔有什么要求了
    2023-02-02
  • java web SpringMVC后端傳json數(shù)據(jù)到前端頁面實例代碼

    java web SpringMVC后端傳json數(shù)據(jù)到前端頁面實例代碼

    本篇文章主要介紹了java web SpringMVC后端傳json數(shù)據(jù)到前端頁面實例代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下。
    2017-03-03
  • 詳解如何在SpringBoot項目中使用統(tǒng)一返回結(jié)果

    詳解如何在SpringBoot項目中使用統(tǒng)一返回結(jié)果

    在一個完整的項目中,如果每一個控制器的方法都返回不同的結(jié)果,那么對項目的維護和擴展都會很麻煩。因此,本文為大家準(zhǔn)備了SpringBoot項目中使用統(tǒng)一返回結(jié)果的方法,需要的可以參考一下
    2022-10-10

最新評論

道真| 扎赉特旗| 安岳县| 忻州市| 彭州市| 青阳县| 扬州市| 忻州市| 莎车县| 民乐县| 曲阳县| 方正县| 金溪县| 遂昌县| 朝阳区| 镇康县| 平武县| 泗洪县| 长白| 定边县| 古丈县| 五河县| 峨眉山市| 长垣县| 福贡县| 视频| 宽城| 东安县| 湘阴县| 富蕴县| 涿州市| 思南县| 布尔津县| 广昌县| 潍坊市| 闽清县| 昔阳县| 益阳市| 商洛市| 台南市| 西丰县|