JAVA 메모리 넘 침 사례 집계

앞 에 쓰다
프로그래머 로 서 많 든 적 든 메모리 가 넘 치 는 장면 을 만 날 수 있 습 니 다.만약 당신 이 아직 만 나 지 못 했다 면,당신 이 일 하 는 연한 이 비교적 짧 을 수도 있 고,아니면 당신 은 근본적으로 가짜 프로그래머 일 수도 있 습 니 다!하하,농담 입 니 다.오늘 우 리 는 자바 코드 의 방식 으로 몇 가지 전형 적 인 메모리 넘 침 사례 를 열거 할 것 입 니 다.여러분 들 이 일상적인 업무 에서 이러한 low 수준의 코드 를 쓰 는 것 을 최대한 피하 시기 바 랍 니 다.
주 클래스 구조 정의
우선,우 리 는 BlowUpJVM 이라는 클래스 를 만 들 었 고 그 후에 모든 사례 실험 은 이 클래스 를 바탕 으로 진행 되 었 다.아래 와 같다.

public class BlowUpJVM { 
} 
스 택 깊이 넘 침

public static void testStackOverFlow(){ 
   BlowUpJVM.testStackOverFlow(); 
} 
스 택 이 계속 재 귀 되 고 처리 되 지 않 아서 가상 컴퓨터 스 택 이 계속 깊이 들 어가 고 스 택 의 깊이 가 이렇게 넘 쳤 습 니 다.
영구 메모리 넘 침

public static void testPergemOutOfMemory1(){ 
  //      
  List<String> list = new ArrayList<String>(); 
  while(true){ 
   list.add(UUID.randomUUID().toString().intern()); 
  } 
} 
String 상수 탱크 를 가득 채 우려 고 했 는데 실패 할 줄 은 몰 랐 습 니 다.JDK 1.7 이후 상수 탱크 를 더미 에 넣 어도 쓰레기 수 거 를 할 수 있 게 되 었 습 니 다.
그리고 다른 방식 으로 cglib 를 사용 하여 Class 로 오래된 연 대 를 가득 채 웁 니 다.

public static void testPergemOutOfMemory2(){ 
  try { 
   while (true) { 
     Enhancer enhancer = new Enhancer(); 
     enhancer.setSuperclass(OOM.class); 
     enhancer.setUseCache(false); 
     enhancer.setCallback(new MethodInterceptor() { 
      @Override 
      public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { 
        return proxy.invokeSuper(obj, args); 
      } 
     }); 
     enhancer.create(); 
   } 
  } 
  catch (Exception e){ 
   e.printStackTrace(); 
  } 
} 
가상 컴퓨터 가 성공 적 으로 메모리 가 넘 쳤 습 니 다.그럼 JDK 동적 에이전트 가 만 든 클래스 가 넘 칠 수 있 습 니까?

public static void testPergemOutOfMemory3(){ 
  while(true){ 
  final OOM oom = new OOM(); 
  Proxy.newProxyInstance(oom.getClass().getClassLoader(), oom.getClass().getInterfaces(), new InvocationHandler() { 
     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 
      Object result = method.invoke(oom, args); 
      return result; 
     } 
   }); 
  } 
} 
사실 에 따 르 면 JDK 동적 에이전트 열등생 의 클래스 는 메모리 가 넘 치지 않 습 니 다.그 이 유 는 JDK 동적 에이전트 가 발생 하 는 클래스 정 보 는 영구적 인 세대 에 넣 지 않 고 쌓 여 있 기 때 문 입 니 다.
로 컬 방법 스 택 넘 침

public static void testNativeMethodOutOfMemory(){ 
  int j = 0; 
  while(true){ 
   Printer.println(j++); 
   ExecutorService executors = Executors.newFixedThreadPool(50); 
   int i=0; 
   while(i++<10){ 
     executors.submit(new Runnable() { 
      public void run() { 
      } 
     }); 
   } 
  } 
} 
이 원 리 는 스 레 드 탱크 를 계속 만 드 는 것 입 니 다.모든 스 레 드 탱크 는 10 개의 스 레 드 를 만 듭 니 다.이 스 레 드 탱크 는 모두 로 컬 방법 구역 에 있 습 니 다.오 랜 시간 이 지나 면 로 컬 방법 구역 이 넘 칩 니 다.
JVM 스 택 메모리 넘 침

public static void testStackOutOfMemory(){ 
  while (true) {  
      Thread thread = new Thread(new Runnable() {  
          public void run() { 
             while(true){ 
           } 
          }  
      });  
      thread.start();  
   }  
}
스 레 드 생 성 은 JVM 스 택 에서 직접 생 성 됩 니 다.그러나 이 예 에서 메모리 가 넘 치 는 것 을 보지 못 했 습 니 다.호스트 가 먼저 끊 었 습 니 다.JVM 이 끊 은 것 이 아니 라 정말 호스트 가 끊 었 습 니 다.mac 에서 든 windows 에서 든 모두 끊 었 습 니 다.
따뜻 한 힌트,이거 진짜 죽 어.
쌓다

public static void testOutOfHeapMemory(){ 
  List<StringBuffer> list = new ArrayList<StringBuffer>(); 
  while(true){ 
   StringBuffer B = new StringBuffer(); 
   for(int i = 0 ; i < 10000 ; i++){ 
     B.append(i); 
   } 
   list.add(B); 
  } 
} 
쌓 아 올 린 StringBuffer 대상 을 계속 끼 워 넣 으 면 바로 넘 칩 니 다.
테스트 사례 전체 코드

public class BlowUpJVM {
  //     
  public static void testStackOverFlow(){ 
   	BlowUpJVM.testStackOverFlow(); 
	} 
  
  //         
  public static void testPergemOutOfMemory1(){ 
    //      
    List<String> list = new ArrayList<String>(); 
    while(true){ 
     list.add(UUID.randomUUID().toString().intern()); 
    } 
  } 
  
  //     
  public static void testPergemOutOfMemory2(){ 
    try { 
     while (true) { 
       Enhancer enhancer = new Enhancer(); 
       enhancer.setSuperclass(OOM.class); 
       enhancer.setUseCache(false); 
       enhancer.setCallback(new MethodInterceptor() { 
        @Override 
        public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { 
          return proxy.invokeSuper(obj, args); 
        } 
       }); 
       enhancer.create(); 
     } 
    } 
    catch (Exception e){ 
     e.printStackTrace(); 
    } 
  } 
  
  //         
  public static void testPergemOutOfMemory3(){ 
    while(true){ 
    final OOM oom = new OOM(); 
    Proxy.newProxyInstance(oom.getClass().getClassLoader(), oom.getClass().getInterfaces(), new InvocationHandler() { 
       public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 
        Object result = method.invoke(oom, args); 
        return result; 
       } 
     }); 
    } 
  } 
  
  //       
  public static void testNativeMethodOutOfMemory(){ 
    int j = 0; 
    while(true){ 
     Printer.println(j++); 
     ExecutorService executors = Executors.newFixedThreadPool(50); 
     int i=0; 
     while(i++<10){ 
       executors.submit(new Runnable() { 
        public void run() { 
        } 
       }); 
     } 
    } 
  } 
  
  //JVM    
  public static void testStackOutOfMemory(){ 
    while (true) {  
        Thread thread = new Thread(new Runnable() {  
            public void run() { 
               while(true){ 
             } 
            }  
        });  
        thread.start();  
     }  
  } 
  
  //   
  public static void testOutOfHeapMemory(){ 
    List<StringBuffer> list = new ArrayList<StringBuffer>(); 
    while(true){ 
     StringBuffer B = new StringBuffer(); 
     for(int i = 0 ; i < 10000 ; i++){ 
       B.append(i); 
     } 
     list.add(B); 
    } 
  } 
} 
마지막 으로 병행 프로 그래 밍 에 습득 해 야 할 핵심 기능 지식 도 를 동봉 합 니 다.여러분 이 병행 프로 그래 밍 을 배 울 때 시행 착 오 를 적 게 걷 기 를 바 랍 니 다.

이상 은 JAVA 메모리 넘 침 사례 를 모 은 상세 한 내용 입 니 다.JAVA 메모리 넘 침 에 관 한 자 료 는 저희 의 다른 관련 글 을 주목 해 주 십시오!

좋은 웹페이지 즐겨찾기