一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術(shù)及軟件下載分享
分類導航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|

服務器之家 - 編程語言 - JAVA教程 - 編寫Java代碼制造一個內(nèi)存溢出的情況

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

2019-12-26 13:14goldensun JAVA教程

這篇文章主要介紹了編寫Java代碼制造一個內(nèi)存溢出的情況,或許這種有意制造能夠更好地幫助理解Java中的內(nèi)存溢出情況XD 需要的朋友可以參考下

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

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

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

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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);
  }
}

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


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

?
1
2
3
4
5
6
7
8
@Override
public boolean equals(Object o) {
  boolean response = false;
  if (o instanceof Key) {
   response = (((Key)o).id).equals(this.id);
  }
  return response;
}

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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);
   }
  }
}

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

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

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


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

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 久久精品国产亚洲AV天美18 | jzjzjz日本在线观看 | 狠狠干2016 | 男公厕里同性做爰 | 久久国产精品永久免费网站 | 996免费视频国产在线播放 | 喷潮女王cytherea全部视频 | 特a级片| 古代翁熄系小说辣文 | 亚洲欧美天堂 | 亚洲欧美优优色在线影院 | 日产国产精品亚洲系列 | 丝袜足控免费网站xx动漫漫画 | 亚洲第99页 | 青草青草视频2免费观看 | 亚洲精品中文字幕在线 | 91香蕉官网 | 午夜爱| 欧美日韩国产一区二区三区在线观看 | 2021国产精品成人免费视频 | 四虎884aa永久播放地址http | 乌克兰成人性色生活片 | 高清日韩在线 | 亚洲国产精品综合久久网络 | 日本中文字幕一区二区三区不卡 | 精品国产香蕉 | 久久国产精品高清一区二区三区 | 午夜影院网页 | 精品视频一区二区三区 | 99爱免费视频 | 美女无内裤下部黄 | 欧美日韩国产一区二区三区欧 | 2018天天拍拍拍免费视频 | 图片一区| 久久人妻少妇嫩草AV无码 | 性福演算法| 亚洲品质自拍视频网站 | 四虎影剧院| 亚久久伊人精品青青草原2020 | 青柠网在线观看视频 | 美女舒服好紧太爽了视频 |