C\#문자열 과 향 원(Flyweight)모드 에 대한 사용 분석

이 글 을 쓰 는 것 은 주로 인터넷 에서 C\#문자열 과 향 원 모드 에 대한 오해 가 많 기 때문이다.
플라이 웨 이 트 모드 에서 이 이름 을 먼저 말 해 보 세 요.플라이 는 파리 입 니 다.맞아요.이 안 은 날 지 않 는 다 는 뜻 입 니 다.파리 라 는 뜻 입 니 다.weight 는 다 들 아 시 겠 지만 무게,파리 의 무게,아주 가볍다 는 뜻 입 니 다.그래서 Flyweight 모드 는 매우 경량급 대상 을 처리 하 는 것 입 니 다.Flyweight 의 목 표 는 대량의 세 립 도 대상 의 메모리 소모 문 제 를 해결 하 는 것 이다.물론 교 부 는 쌀 이 없 는 밥 을 짓 기 어렵 고 그 어떠한 모델 과 기법 도 근거 없 이 메모 리 를 만 들 수 없 기 때문에 향 원 모델 이 겨냥 한 상황 은 이런 세 립 도 대상 의 중 데이터 가 중복 되 는 상황 이다.플라이 웨 이 트 는 대상 의 상태(보통 속성 으로 표시)를 두 부분 으로 나 누 어 일 부 는 내부 상태 이 고 다른 일 부 는 외부 상태 이다.내부 상태 외부 상 태 는 중복 되 기 쉽 지 않 고 외부 상태 내부 상 태 는 중복 되 기 쉽다.그래서 Flyweight 는 외부 상 태 를 추출 하여 공유 함으로써 메모리 점용 문 제 를 어느 정도 해결 했다.
C\#의 문자열 은 Flyweight 모드 가 아니 라 인터넷 에서 흔히 볼 수 있 는 표현 입 니 다.C\#의 문자열 은 Flyweight 모드 를 사 용 했 습 니 다.이 표현 은 틀 렸 습 니 다.어디 가 틀 렸 지?위의 설명 에 따 르 면'내부 상태 외부 상태'라 는 문자열 이 잘못 되 었 습 니 다.일반적으로 문자열 이 향 원 인 이 유 는 다음 과 같은 코드 입 니 다.string a="Hello World";Console.WriteLine(Object.ReferenceEquals(a, "Hello World")); //True 는 문자열 의 직접 양 을 사용 할 때'Hello World'를 얼마나 썼 든 간 에 최종 메모리 에는 문자열 대상 이 하나 밖 에 없습니다.실행 할 때 만 든 문자열 은 이 열 에 있 지 않 습 니 다.메모리 에 새로운 문자열 을 강제로 만 들 수 있 습 니 다.string a = "Hello World"; Console.WriteLine(Object.ReferenceEquals(a, new String("Hello World".ToCharArray())));  //False 는 new 를 강제로 호출 했 기 때문에 이 문자열 은 메모리 의 직접'Hello World'에 대응 하 는 대상 과 같 지 않 습 니 다.재 미 있 는 것 은 C\#문자열 풀 에 문자열 을 강제로 추가 할 수 있 습 니 다.string a = "Hello World"; string b = String.Intern(new String("Hello World".ToCharArray())); Console.WriteLine(Object.ReferenceEquals(a,b) );    또는 string a=String.Intern(new String("Hello World".ToCharArray())));string b = String.Intern(new String("Hello World".ToCharArray())); Console.WriteLine(Object.ReferenceEquals(a,b) );앞에서 언급 한 바 와 같이 이 행 위 는 Flyweight 가 사용 하 는 내부 상태 와 외부 상태 와 달리 두 대상 이 실제로 같은 대상 이다.
C\#의 문자열 은 Flyweight 모드 와 좋 습 니 다.앞에서 많이 말 했 습 니 다.C\#의 문자열 은 Flyweight 모드 가 아 닙 니 다.하지만 C\#안의 문자열 은 Flyweight 와 관계 가 없다 는 것 을 의미 하 는 것 이 아 닙 니까?물론 아 닙 니 다.그렇지 않 으 면 제 가 이런 글 을 쓰 는 것 은 너무 아 프 지 않 습 니까?문자열 풀 과 Intern 방법 은 정말 Flyweight 를 실현 하 는 신기 입 니 다!우리 에 게 어떤 대상 이 있 는 지 고려 하면 수백 만 개 를 만 들 수 있 습 니 다.대상 안에 마침 이런 속성 이 있 습 니 다.이것 은 대상 이 구 조 될 때 무 작위 로 생 성 됩 니 다.색 채 는 rgb 색 을 사용 하고 rgb 24 로 표시 합 니 다.그래서 색 문자열 은\#ccc 와 유사 합 니 다.코드 를 쓰 면 아래 와 같 습 니 다:

    class Element
    {
 static Random rnd = new Random();
 static char[] table;
 static Element()
 {
     table = "0123456789abcdef".ToCharArray();
 }
 public string color;
 public Element()
 {
     color = "" + table[rnd.Next() % 16] + table[rnd.Next() % 16] + table[rnd.Next() % 16];
 }
    }
다음 에 3 천만 개의 대상 을 만들어 서

     Element[] eles = new Element[30000000];
     for (var i = 0; i < 30000000; i++)
     {
  eles[i] = new Element();
     }
을 만 드 는 방법 을 보 겠 습 니 다.
작업 관리자 에서 큰 메모리 가 먹 히 는 것 을 보 았 다.
QFOMR9}(NR%(T3`V3Q35MSY
그 다음 에 우 리 는 String.Intern 을 사용 하여 Flyweight:

    class Element
    {
 static Random rnd = new Random();
 static char[] table;
 static Element()
 {
     table = "0123456789abcdef".ToCharArray();
 }

 public string color;
 public Element()
 {
     color = String.Intern("" + table[rnd.Next() % 16] + table[rnd.Next() % 16] + table[rnd.Next() % 16]);
 }
    }

을 실현 하면 메모리 사용량 의 뚜렷 한 변 화 를 볼 수 있 습 니 다.문자열 대상 의 변경 할 수 없 는 성질 때문에 String.Intern 을 사용 한 후에 우 리 는 앞 뒤 color 의 차 이 를 전혀 알 수 없습니다.즉,앞 뒤 Element 류 를 수정 하 는 것 은 똑 같은 효 과 를 가 집 니 다.그러나 Flyweight 는 우리 에 게 대량의 메모 리 를 절약 해 주 었 습 니 다.
이 전형 적 인 flyweight 장면 을 사용 하여 우리 에 게 향 원 외부 상태 내부 상태의 특징 을 밝 혔 다.문자열 처럼 변경 할 수 없 는 대상 이다.GoF 원서 의 예 중 글꼴 대상 인 글 립 스 도 마찬가지다.String.Intern 이라는 대상 풀 의 방식 으로 fly weight 를 실현 하 는 것 도 참고 할 만하 다.우 리 는 fly weight 의 외부 상태 대상 을 디자인 할 때 비슷 한 방식 을 사용 하 는 것 을 고려 할 수 있다.

좋은 웹페이지 즐겨찾기