>  기사  >  Java  >  Java의 일반적인 메모리 누수 문제 및 솔루션

Java의 일반적인 메모리 누수 문제 및 솔루션

高洛峰
高洛峰원래의
2017-01-16 16:07:311547검색

Q: Java에서는 메모리 누수가 어떻게 발생할 수 있나요?
A: Java에서는 메모리 누수가 발생하는 데에는 여러 가지 이유가 있습니다. 전형적인 예는 hasCode 및
equals 메소드를 구현하지 않고 HashMap에 저장되는 Key 클래스입니다. 결국, 많은 중복 개체가 생성됩니다. 모든 메모리 누수
는 결국 OutOfMemoryError 예외를 발생시킵니다. 다음은 무한 루프를 통해 메모리 누수
를 시뮬레이션하는 간단한 예입니다.

import java.util.HashMap;
import java.util.Map;

public class MemoryLeak {

 public static void main(String[] args) {
  Map<Key, String> map = new HashMap<Key, String>(1000);

  int counter = 0;
  while (true) {
       // creates duplicate objects due to bad Key class
   map.put(new Key("dummyKey"), "value");
   counter++;
   if (counter % 1000 == 0) {
    System.out.println("map size: " + map.size());
    System.out.println("Free memory after count " + counter
      + " is " + getFreeMemory() + "MB");

    sleep(1000);
   }

    
  }
 }

 // inner class key without hashcode() or equals() -- bad implementation
 static class Key {
  private String key;

  public Key(String key) {
   this.key = key;
  }

 }

 //delay for a given period in milli seconds
 public static void sleep(long sleepFor) {
  try {
   Thread.sleep(sleepFor);
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
 }

 //get available memory in MB
 public static long getFreeMemory() {
  return Runtime.getRuntime().freeMemory() / (1024 * 1024);
 }

}

결과는 다음과 같습니다.

map size: 1000
Free memory after count 1000 is 4MB
map size: 2000
Free memory after count 2000 is 4MB
map size: 1396000
Free memory after count 1396000 is 2MB
map size: 1397000
Free memory after count 1397000 is 2MB
map size: 1398000
Free memory after count 1398000 is 2MB
map size: 1399000
Free memory after count 1399000 is 1MB
map size: 1400000
Free memory after count 1400000 is 1MB
map size: 1401000
Free memory after count 1401000 is 1MB
.....
.....
map size: 1452000
Free memory after count 1452000 is 0MB
map size: 1453000
Free memory after count 1453000 is 0MB
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
 at java.util.HashMap.addEntry(HashMap.java:753)
 at java.util.HashMap.put(HashMap.java:385)
 at MemoryLeak.main(MemoryLeak.java:10)

Q: 위의 메모리 누수를 어떻게 해결하나요?
A: Key 클래스의 equals 및 hasCode 메소드를 구현하세요.

    .....
static class Key {
 private String key;

 public Key(String key) {
  this.key = key;
 }

 
 @Override
 public boolean equals(Object obj) {

  if (obj instanceof Key)
   return key.equals(((Key) obj).key);
  else
   return false;

 }

 @Override
 public int hashCode() {
  return key.hashCode();
 }
}
.....

프로그램을 다시 실행하면 다음과 같은 결과를 얻게 됩니다.

 map size: 1
Free memory after count 1000 is 4MB
map size: 1
Free memory after count 2000 is 4MB
map size: 1
Free memory after count 3000 is 4MB
map size: 1
Free memory after count 4000 is 4MB
...
Free memory after count 73000 is 4MB
map size: 1
Free memory after count 74000 is 4MB
map size: 1
Free memory after count 75000 is 4MB

Q: 실제 시나리오에서 메모리 누수를 어떻게 찾나요?
A: 다음 코드를 통해 스레드 ID 가져오기

C:\>jps
5808 Jps
4568 MemoryLeak
3860 Main

명령줄을 통해 jconsole 열기

C:\>jconsole 4568

hasCode 및 equals를 구현한 Key 클래스와 구현하지 않은 차트는 다음과 같습니다.

메모리 누수 없음:

Java의 일반적인 메모리 누수 문제 및 솔루션

메모리 누수 발생:

Java의 일반적인 메모리 누수 문제 및 솔루션

Java의 일반적인 메모리 누수 문제 및 해결 방법에 관한 기사는 PHP 중국어 웹사이트를 주목하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.