亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

編寫Java代碼制造一個(gè)內(nèi)存溢出的情況

 更新時(shí)間:2015年07月10日 12:02:40   投稿:goldensun  
這篇文章主要介紹了編寫Java代碼制造一個(gè)內(nèi)存溢出的情況,或許這種有意制造能夠更好地幫助理解Java中的內(nèi)存溢出情況XD 需要的朋友可以參考下

 這將會是一篇比較邪惡的文章,當(dāng)你想在某個(gè)人的生活中制造悲劇時(shí)你可能會去google搜索它。在Java的世界里,內(nèi)存溢出僅僅只是你在這種情況下可能會引入的一種bug。你的受害者會在辦公室里度過幾天甚至是幾周的不眠之夜。

在這篇文章中我將會介紹兩種溢出方式,它們都是比較容易理解和重現(xiàn)的。并且它們都是來源現(xiàn)實(shí)項(xiàng)目的案例研究,但是為了讓你清晰地掌握,我把它們簡化了。

不過放心,在我們遇到和解決了很過溢出bug之后,類似的案例將會比你想象得更加普遍。

先來一個(gè)進(jìn)入狀態(tài)的,在使用HashSet/HashMap時(shí),所用鍵值沒有或者其equals()/hashCode()方法不正確,這會導(dǎo)致一個(gè)臭名昭著的錯(cuò)誤。
 

class KeylessEntry {
 
  static class Key {
   Integer id;
 
   Key(Integer id) {
     this.id = id;
   }
 
   @Override
   public int hashCode() {
     return id.hashCode();
   }
  }
 
  public static void main(String[] args) {
   Map m = new HashMap();
   while (true)
     for (int i = 0; i < 10000; i++)
      if (!m.containsKey(i))
        m.put(new Key(i), "Number:" + i);
  }
}

當(dāng)你運(yùn)行上面的代碼時(shí),你可能會期望它運(yùn)行起來永遠(yuǎn)不會出問題,畢竟內(nèi)置的緩存方案只會增加到10,000個(gè)元素,然后就不會再增加了,所有的key都已經(jīng)出現(xiàn)在 HashMap中。然而,事情并非如此。元素將會一直增長, 因?yàn)镵ey這個(gè)類沒有在hashCode()后實(shí)現(xiàn)一個(gè)合適的equals()方法。


解決方法很簡單,只要和下面的示例一樣添加一個(gè)equals方法就可以了。但是在找到問題所在之前,你肯定已經(jīng)花費(fèi)了不少寶貴的腦細(xì)胞。
 

@Override
public boolean equals(Object o) {
  boolean response = false;
  if (o instanceof Key) {
   response = (((Key)o).id).equals(this.id);
  }
  return response;
}

下一個(gè)你得提醒朋友的是和String處理相關(guān)的操作。它的表現(xiàn)會很詭異,特別是結(jié)合JVM版本差異的時(shí)候。String的內(nèi)部工作機(jī)制在 JDK 7u6中被改變了,所以如果你發(fā)現(xiàn)產(chǎn)品環(huán)境只是小版本號的區(qū)別,那么你已經(jīng)準(zhǔn)備好條件了。把類似下面的代碼給你的朋友調(diào)試,然后問他為什么這個(gè)bug只會在產(chǎn)品中出現(xiàn)。
 

class Stringer {
  static final int MB = 1024*512;
 
  static String createLongString(int length){
   StringBuilder sb = new StringBuilder(length);
   for(int i=0; i < length; i++)
     sb.append('a');
   sb.append(System.nanoTime());
   return sb.toString();
  }
 
  public static void main(String[] args){
   List substrings = new ArrayList();
   for(int i=0; i< 100; i++){
     String longStr = createLongString(MB);
     String subStr = longStr.substring(1,10);
     substrings.add(subStr);
   }
  }
}

上面的代碼出了什么問題呢?當(dāng)它在JDK 7u6之前的版本上運(yùn)行的時(shí)候,返回的字符串將會保存一個(gè)對那個(gè)1M左右大小的字符串的引用,如果你運(yùn)行的時(shí)候設(shè)置為-Xmx100m,你會得到一個(gè)意想不到的oom錯(cuò)誤。結(jié)合你實(shí)驗(yàn)環(huán)境中平臺和版本的差異,傷腦經(jīng)的事情就產(chǎn)生了。

現(xiàn)在如果你想掩蓋你的足跡,我們可以引進(jìn)一些更加高級的概念。比如

  •     在不同的類加載器中載入有破壞性的代碼,在加載的類被原始類加載器刪除后保持對它的引用,可以模擬一個(gè)類加載器溢出
  •     把攻擊性的代碼隱藏在finalize方法中,使得程序表現(xiàn)變得不可預(yù)測
  •     在一個(gè)長期運(yùn)行的線程中加入棘手的組合,它可能在ThreadLocals中保存了一些可以被線程池訪問的東西,以便管理應(yīng)用線程。


我希望我們給了你一些思考的原材料以及當(dāng)你想修理某人時(shí)的一些素材。這將帶來無窮無盡的調(diào)試。除非你的朋友使用 Plumbr來查找溢出的所在地。

相關(guān)文章

  • IDEA實(shí)現(xiàn)序列化時(shí)如何自動生成serialVersionUID的步驟

    IDEA實(shí)現(xiàn)序列化時(shí)如何自動生成serialVersionUID的步驟

    這篇文章主要介紹了IDEA實(shí)現(xiàn)序列化時(shí)如何自動生成serialVersionUID的步驟,首先安裝GenerateSerialVersionUID插件,當(dāng)出現(xiàn)添加serialVersionUID選項(xiàng),選中則會自動生成serialVersionUID,感興趣的朋友一起學(xué)習(xí)下吧
    2024-02-02
  • Java中多種循環(huán)Map的常見方式詳解

    Java中多種循環(huán)Map的常見方式詳解

    Java中的Map是一種鍵值對存儲的數(shù)據(jù)結(jié)構(gòu),其中每個(gè)鍵都唯一,與一個(gè)值相關(guān)聯(lián),下面這篇文章主要給大家介紹了關(guān)于Java中多種循環(huán)Map的常見方式,文中給出了詳細(xì)的代碼示例,需要的朋友可以參考下
    2024-01-01
  • java使用鏈表來模擬棧的入棧出棧操作實(shí)例代碼

    java使用鏈表來模擬棧的入棧出棧操作實(shí)例代碼

    這篇文章主要介紹了java 使用鏈表來模擬棧的入棧出棧操作,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • SpringBoot中的@RestControllerAdvice注解詳解

    SpringBoot中的@RestControllerAdvice注解詳解

    這篇文章主要介紹了SpringBoot中的@RestControllerAdvice注解詳解,RestControllerAdvice注解用于創(chuàng)建全局異常處理類,用于捕獲和處理整個(gè)應(yīng)用程序中的異常,需要的朋友可以參考下
    2024-01-01
  • java操作ftp下載文件示例

    java操作ftp下載文件示例

    這篇文章主要介紹了java操作ftp下載文件的示例,需要的朋友可以參考下
    2014-02-02
  • Spring?Cloud?Gateway編碼實(shí)現(xiàn)任意地址跳轉(zhuǎn)的示例

    Spring?Cloud?Gateway編碼實(shí)現(xiàn)任意地址跳轉(zhuǎn)的示例

    本文主要介紹了Spring?Cloud?Gateway編碼實(shí)現(xiàn)任意地址跳轉(zhuǎn)的示例,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-12-12
  • Springboot中@scheduled注解解析

    Springboot中@scheduled注解解析

    這篇文章主要介紹了Springboot中@scheduled注解解析,定時(shí)任務(wù)就是在指定時(shí)間執(zhí)行程序,或周期性執(zhí)行計(jì)劃任務(wù),Java中實(shí)現(xiàn)定時(shí)任務(wù)的方法有很多,本文從從JDK自帶的一些方法來實(shí)現(xiàn)定時(shí)任務(wù)的需求,需要的朋友可以參考下
    2023-09-09
  • MongoDB 整合SpringBoot舉例介紹

    MongoDB 整合SpringBoot舉例介紹

    這篇文章主要介紹了MongoDB 整合SpringBoot的相關(guān)知識,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2025-05-05
  • SpringBoot如何監(jiān)控Redis中某個(gè)Key的變化(自定義監(jiān)聽器)

    SpringBoot如何監(jiān)控Redis中某個(gè)Key的變化(自定義監(jiān)聽器)

    這篇文章主要介紹了SpringBoot如何監(jiān)控Redis中某個(gè)Key的變化(自定義監(jiān)聽器),具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • 關(guān)于快速測試API接口的一個(gè)新技能

    關(guān)于快速測試API接口的一個(gè)新技能

    這篇文章主要給大家介紹了關(guān)于快速測試API接口的一個(gè)新技能,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-06-06

最新評論