Java 코드를 작성하여 메모리가 넘치는 상황을 만들다

이것은 비교적 사악한 문장이 될 것이다. 누군가의 삶에서 비극을 만들고 싶을 때 구글에 가서 그것을 검색할 수도 있다.자바의 세계에서 메모리가 넘치는 것은 단지 당신이 이런 상황에서 도입할 수 있는 버그일 뿐이다.너의 피해자는 사무실에서 며칠, 심지어 몇 주 동안의 잠 못 이루는 밤을 보낼 것이다.
이 문장에서 나는 두 가지 넘침 방식을 소개할 것이다. 그것들은 모두 비교적 쉽게 이해하고 재현할 수 있다.그리고 그것들은 모두 현실 프로젝트의 사례 연구에서 나온 것이지만, 당신이 명확하게 파악하기 위해 나는 그것들을 간소화했다.
그러나 안심하세요. 우리가 과도한 버그를 만나고 해결한 후에 유사한 사례는 생각보다 더욱 보편적일 것입니다.
먼저 상태로 들어갑니다. HashSet/HashMap을 사용할 때 사용한 키 값이 없거나 equals()/hashCode() 방법이 정확하지 않으면 악명 높은 오류가 발생할 수 있습니다.
 

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);
  }
}
위의 코드를 실행할 때, 내장된 캐시 방안은 10000개의 요소만 증가하고, 더 이상 증가하지 않을 것이며, 모든 키는HashMap에 이미 등장할 것이다.그러나 일은 그렇지 않다.키 종류는hashCode () 다음에 적합한 equals () 방법을 실현하지 않았기 때문에 원소는 계속 증가할 것이다.
해결 방법은 간단합니다. 아래의 예시와 같이 equals 방법을 추가하면 됩니다.하지만 문제점을 찾기 전에 귀중한 뇌세포를 많이 썼을 것이다.
 

@Override
public boolean equals(Object o) {
  boolean response = false;
  if (o instanceof Key) {
   response = (((Key)o).id).equals(this.id);
  }
  return response;
}
다음은 String 처리와 관련된 작업이라는 것을 친구에게 일깨워 주어야 합니다.특히 JVM 버전 차이와 결합할 때 그 표현은 매우 기괴할 수 있습니다.String의 내부 작업 메커니즘이 JDK 7u6에서 바뀌었기 때문에 제품 환경이 작은 버전 번호의 차이일 뿐이라는 것을 발견하면 당신은 이미 조건을 준비했다.아래와 같은 코드를 친구에게 디버깅해 보고 왜 이 버그가 제품에만 나타나는지 물어보세요.
 

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 정도 크기의 문자열에 대한 인용을 저장합니다. 실행할 때 -Xmx100m로 설정하면 예상치 못한 oom 오류가 발생합니다.실험 환경에서 플랫폼과 버전의 차이를 결합하면 뇌경을 상하게 하는 일이 생긴다.
지금 만약 네가 너의 발자취를 감추고 싶다면, 우리는 좀 더 고급스러운 개념을 도입할 수 있다.예컨대
  • 서로 다른 클래스 캐리어에 파괴적인 코드를 불러옵니다. 불러오는 클래스가 원시 클래스 캐리어에 의해 삭제된 후에 인용을 유지하면 클래스 캐리어가 넘치는 것을 모의할 수 있습니다
  • 공격적인 코드를finalize 방법에 숨겨서 프로그램의 표현을 예측할 수 없게 만든다
  • 장기적으로 실행되는 라인에 까다로운 조합을 추가합니다. 이것은 ThreadLocals에 스레드 탱크에 접근할 수 있는 것들을 저장하여 응용 라인을 관리할 수 있습니다
  • 나는 우리가 너에게 생각하는 원자재와 누군가를 수리하고 싶을 때의 소재를 주었으면 좋겠다.이것은 무궁무진한 디버깅을 가져올 것이다.당신의 친구가 사용하지 않는 한Plumbr 넘치는 소재지를 찾아라.

    좋은 웹페이지 즐겨찾기