이 항목의 요점은 쓸데없이 여러개의 객체를 생성하지 말자 라는겁니다. 싱글톤과는 다른 이야기입니다.

예를들자면 몬스터 헌터(이하 몬헌)를 하려고 PSP를 샀습니다.
용을 잡았습니다.
용을 잡았으니까 PSP를 버렸습니다.

다음날이 됬습니다.
몬헌이 하고싶어졌습니다.
PSP를 샀습니다.
용을 잡았습니다.
게임기를 버립니다.

다음날이 됬습니다.
몬헌이 하고싶어졌습니다.
PSP를 샀습니다.
용을 잡았습니다.
게임기를 버립니다.

다음날이 됬습니다.
몬헌이 하고싶어졌습니다.
PSP를 샀습니다.
용을 잡았습니다.
게임기를 버립니다.

다음날이 됬습니다.
몬헌이 하고싶어졌습니다.
PSP를 샀습니다.
용을 잡았습니다.
게임기를 버립니다.

여기서 발생하는 문제가 무엇인가요?
잘모르겠다고 하시는분은 프로그래밍을 그만두는 편이 좋을거 같습니다.(그돈을 나에게 달라고..)

몬헌을 하기위해서 항상 PSP를 사는데 필요한 돈과 시간이 필요합니다.

그렇다면 해결방법은 무엇일까요?

그냥 처음에 PSP를 한대 사놓고 계속 쓰는겁니다.
간단하죠?

그러다가 가족과 같이 하고싶어지면 그때 한대 더사면 됩니다.

프로그래밍에서도 위와같은 실수를 하는 경우가 종종 있습니다.

String 의 경우에는 객체를 생성하는 두가지 방법이 있는데
String s1=new String("Hello");

String s2="Hello";
의 두가지 형식이 있다는것은 다들 잘 아실겁니다.

만약 printHello() 라는 "Hello" 를 출력하는 함수가 있다고 가정합시다.
이때 System.out.println("Hello"); 라고 하는것과 System.out.println(new String("Hello")); 라고 하는것과 어떤 차이가 있을까 하는 겁니다.
리터럴의 개념을 알고 있다면 쉽게 이해를 할수 있을겁니다.
"Hello" 라는 리터럴을 printHello()에서 사용하지만 쳣번째는 리터럴을 그대로 사용하고 두번째는 "Hello"라는 리터럴을 이용해서 객체를 생성한 뒤 "Hello"를 출력합니다.

만약 new String()을 사용하는 printHello()를 100번을 호출했다면?
위에 예를 든 내용에서 PSP를 100대 사고 버린것과 같은짓을 한겁니다.

또한가지 예를 들어보면
Long sum=0l;
for(long i=0;i<Integer.MAX_VALUE ; i++){
	sum+=i;
}
System.out.println(sum);
위의 코드에서 어떤 문제가 생길까요? Long는 L이 대문자라서 버그입니다. 라고 말한다면 자바공부를 좀더 하셔야겠습니다.

실행해보면 미친듯이 느립니다.

제 컴퓨터에서는 24초쯤 걸렸네요. 책의 저자는 43초 걸렸다고 합니다.
0~20억까지 더하니까 별수 없다 라고 할수도 있겠지만 문제를 찾았다면 자바의 오토박싱이라는것에 대해서 잘 알고있는 사람일것입니다.

Long 를 사용하게되면 일반적인 연산을하기 위해서는 항상 박싱과 언박싱을 해야합니다.
그러는 과정에서 상당한 자원소모가 발생하기 때문에 Long sum=0l;을 long sum=0; 으로 바꾸는것만으로 걸리는 시간이 5초로 줄어들었습니다. 속도가 5배나 빨라졌습니다!

책에서는 이 항목을 객체 생성은 비용이 많이 드니까 하면 피해야한다 라는 의미로 해석하면 안된다고 합니다.

위에 예를 들었던 이야기에서 형제끼리 PSP를 하려고 한다면 PSP가 비싸니까 한대만 샀다 라고 합시다.
그렇게 되면 형제끼리 PSP를 두고 싸우게됩니다. 그에 따라 발생하는 손실비용이 PSP를 구입하는 것 보다 더 클지도 모릅니다.

따라서 형제의 우애를 위해서 장난감은 머릿수만큼 사줍시다!

또한 책의 뒤에 있는 내용을보면 방어 복사 라는것이 나오는데 방어복사를 함으로써 발생하는 자원손실 보다 방어복사를 통한 시스템 안정성향상에 의한 이득이 더 크다 라는 내용도 있으니 상황에 따라 적절히 써야겠습니다.
Posted by 동적할당
: