부적절한 사용으로 인한 메모리 유출 문제 집합

14475 단어 java 기초
HashMap과HashSet을 다시 사용할 때, 우리는 항상 키로 대상을 사용자 정의합니다.사용자 정의 대상을 사용할 때 대상 내의 속성을 사용하여HashCode를 생성할 경우 이 대상의setter 방법을 제공하지 마십시오. 즉 키는 변하지 않는 클래스이어야 하며, 그렇지 않으면 메모리 유출을 초래할 수 있습니다.

코드 예

package trysome.doYourSelf;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

public class Lokk {

    private static class People{
        int age;
        String name;

        People(String name,int age){
            this.name=name;
            this.age=age;
        }

        @Override
        public int hashCode() {
            //   People HashCode
            return age+name.hashCode();
        }

        @Override
        public boolean equals(Object obj) {
            if (obj==this){
                return true;
            }
            if (obj instanceof People){
                return this.hashCode()==obj.hashCode();
            }
            return false;
        }

        public void setAge(int age) {
            this.age = age;
        }

        @Override
        public String toString() {
            return "People{" +
                    "age=" + age +
                    ", name='" + name + '\'' +
                    '}';
        }
    }

    public static void main(String[] args) {

        People p1=new People("aa",1);
        People p2=new People("aa",2);

        Map<People,Integer> map=new HashMap<>();
        map.put(p1,111);
        map.put(p2,111);

        p1.setAge(23);
        map.remove(p1);
        //    1, 2, p1 
        System.out.println(map.size());
        //   
        System.out.println(map.toString());

        System.out.println("--------------------");

        //   p1 map
        map.put(p1,111);
        System.out.println(map.size());//   3, 
        //    :
        // {People{age=23, name='aa'}=111, People{age=2, name='aa'}=111, People{age=23, name='aa'}=111}
        //   2 
        System.out.println(map.toString());

        System.out.println("--------------------");

        //   
        map.remove(p1);
        map.remove(p1);
        //  {People{age=23, name='aa'}=111, People{age=2, name='aa'}=111}: 
        System.out.println(map.toString());

        Integer re=map.get(p1);
        System.out.println(re);//   null: , , 。。。
    }
}

왜 p1의age 속성을 수정한 후에removep1을 사용할 때 삭제할 수 없습니까?왜 다시 넣을 때 넣을 수 있어요?여기는HashMap의put작업과 관련이 있습니다. 처음 p1을 넣었을 때 p1의age,name 속성("aa",1)에 따라hashcode1을 생성하고hashcode에 따라 해시표의 아래 표시인 index1을 얻어 체인을 끊습니다.p1의age 속성을 수정한 후 p1을 삭제하든지 p1의age,name 속성을 통해hashcode2를 얻어서 해시표의 아래에 있는 index2로 포지셔닝해야 한다. 그러나ag2는 23이다. 즉,hashcode1과hashcode2는 다르기 때문에 포지셔닝된 index2도 다르기 때문에 삭제할 수 없다. index2 위치는 현재 요소가 없다.같은 이치로 p1을 다시 넣을 때 index2에 대응하는 위치를 넣는다. 넣은 후에 index1 위치의 요소가 존재하지만 인용을 잃었기 때문에 얻을 수도 삭제할 수도 없고 메모리 유출이 발생한다.다음에 넣은 것은 p1이 인용하고 있기 때문에 삭제할 수 있습니다.
총괄: 맵에 넣은 키를 변하지 않는 대상으로 하고 무심코 변경된 메모리 유출을 줄인다.

좋은 웹페이지 즐겨찾기