반응형
자바 프로그래밍을 할때 java.lang 패키지 안의 클래스중 가~~장 많이 쓰는클래스는 무엇일까?

의심할 여지도없다.. 단연 String 문자열 클래스이다.

"그냥 단순 쓰면되지.. 머~~"  하는 그런식의 클래스처럼 보이긴 하나,, 자바에서 튜닝을 결정짓는

꽤중요한 잣데 역할을 하기도한다.

String Class에 대해 낯낯히 파해쳐 보도록 하자.

[1] String Class의 이해

말은 String Class의 이해라고 하지만 1번 절에서는 간단하게 초보 프로그래머가 실수를 범하는 간단한 사례에 대해서
설명해 보도록 하겠다.

나도 그랬지만, 대학교 jsp시간에 학교에서 가르칠때에는 String Class의 사용법을 잘못 알려주는 곳이 많다.
예를들어서 JDBC를 연결하여 DB를 조회하는 간단한 QUERY를 작성 한다고 가정하였을때, 우리는 이렇게 짠다.

String query= "SELECT "+
                    "name, id, password "+
                    " from temptable";


머 이런식으로 + 연산자를 사용해서 줄줄이 붙여나가는 식이다. 흠.~~~~

예제는 저렇게 간단하지만, 필드에 나갔을때 통계쿼리를 작성한다고 가정하면 150줄이상되는 쿼리들으 엄청많음을

유의해야한다.

그렇다면~~!

과연 저것이 정석인 것인가? ..저런 방법을 사용하게 되면 개발자 입장에서 손가락이 편할지는 모르겠지만,

시스템 입장에서는 메모리를 많이 차지 하기 때문에 전체적으로 좋지 않은 습관중 하나이다.

실질적으로 한빛 미디어에서 나온 "자바성능을 결정짓는 코딩습관" 이란 책에서 이것에 대해 메모리사용량을

PLAN을 떠놓았다.

구분 결과
메모리 사용량 10회 평균 약 5MB
응답시간 10회 평균 약 5ms
           [ 위의 query를 100회 수행하였을때 메모리 변화와 응답시간 ]

흠... 대충보면 머~~ 저정도야 하겠지만, 저건 엄청난 메모리 수치이다. 쿼리문 하나 100회 돌리는데 5M가든다고

가정하였을때,, 만약  필드에 나가 대민서비스를 한다고 생각해 보아라.그럼 분명... 서버는 메모리 부족현상이

일어날 확률이많을 것이다. 그럼 이러한 것을 고려하여 코딩하는 좋은 습관은 무엇인지 알아보자.

[2] StringBuilder / StringBuffer Class의 이해

String 관련 Class중 StringBuilder 와 StringBuffer 클래스가 존재한다. 결론부터 애기하자면 DB의 QUERY문과 같이

아주 긴~ 문자열을 이을때는 String < StringBuilder < StringBuffer 와 같은 순으로 쓰는것이좋다. 결국 StringBuffer

Class를 사용하라는 것이다.

StringBuilder 와 StringBuffer의 차이점은 크지않다. 단지 StringBuffer 클래스가 멀티스레드에 안정적이게 돌아간다는것

뿐이다. StringBuilder는 단일스레드에서 호출할때를 고려해서 만든 클래스이기 때문에 멀티스레드에서는 안정성을

보장받지 못한다. 성능상으로는 두 클래스는 큰 차이가 없다.

그럼 [1] 의 query를 StringBuilder 로 변환하였을때 메모리 사용량과 응답시간에 대해 알아보도록 하자.

StringBuilder builder = new StringBuilder()'
builder.append("SELECT");
builder.append("name, id, password ");
builder.append("from temptable");


이렇게 바꾸어보도록 하자. 아래표를 주시 해야한다.

구분 결과
메모리 사용량 10회 평균 약 371KB
응답시간 10회 평균 약 0.3ms
 [ StringBuilder를 이용하여 위 쿼리를 100번 수행했을때 결과 ]


결과를 보라 놀랍지 않은가?? 뜨~~~아...

이제 왜 장문의 긴 문자열 입력시 StringBuilder 또는 StringBuffer를 사용해야하는지 이해가 될것이다.

그럼 왜 이렇게 차이가 나는것일까? 라는 의문증이 생긴다.

[3] String클래스 와 StringBuilder / StringBuffer 클래스의 차이점.

해당 차이점에 대해 그림으로 간단히 설명해보이겠다.

[ String Class의 메모리 사용 예제 ]

100 SELECT
105 SELECT name, id, password 
110 SELECT name, id, password  from temptable


[ StringBuilder / StringBuffer의 메모리 사용예제 ]

100 SELECT
100 SELECT name, id, password 
100 SELECT name, id, password  from temptable

차이점이 보이는가?

String Class의 경우는 메번 + 연산자를 통해서 append작업시 메모리를 새로 할당하게 된다.

따라서 GC가 수행되거나 해당 프로세스가 끝나기 전까지는 메모리가 죽지 않고 살아있기 때문에 메모리를 굉장히 많이

먹는 케이스이다. 물론 매번 복사하기 때문에 수행시간역시 오래걸린다.

하지만, StringBuilder / StringBuffer 클래스는 같은 메모리번지의 공간을 할당한 다음 유동적으로 데이터를 append

하는 모습을 그림으로 볼수 있을것이다.

모두들 아하~~! 라는 생각이 들었는지 모르겠다. 결국 append하는 방법의 차이이다.

[4] Version 별로 알아보는 문자열 Class

이제 내 글을 읽은 아무개 사람들은 분명 생각할 것이다. StringBuffer 클래스만 쓰자!!! ㅋㅋ

중독증세다.. 절대 그러지마라.. JDK 1.4버젼까지만 저렇게 구동하였을뿐 , 1.5부터는 컴파일 시점에

String 클래스의 + 연산자를 StringBuffer클래스의 append 연산자로 바뀌기 때문이다.

눈으로 확인하고 싶다고???????? 1.5에서 decompile한번 해봐라~~ 그럼 확실히 소스로서 차이점을

알수 있을것이다.

[5] 결론

대망의 결론이다. 매우 좋지만, 때론 그지같은 String클래스에 대해서 알아봤다. [4] 번에서 보듯이 버젼별 차이가

있긴하지만, 필드에서 어떤버젼을 사용할지는모른다. 실제 1.4에서 경험을 많이한 나로서는 String 클래스를 쓰는데

더욱 조심하게 되었다. 결론은 이것이다.

좀 짧다 싶은 문자열은 String를 사용하고 좀 길다 싶은 문자열은 StringBuilder  /  StringBuffer 클래스를 사용하는것이.

개발자의 습관상 아주 바람직한 이상향이라고 하겠다. 아.. 벌써 새벽 1시 30분이 다되었군...

휴~~~ 새벽 1시에 잠안와서 머하는짓인지 모르겠다만,,, 내일지각하면 연차 깍이기 때문에 오타는 다음에 수정하도록

하고 잠을 자야겠다~ ㅋㅋ

그럼 모두들 공부 열심히 하세용.
반응형

'Program > JAVA' 카테고리의 다른 글

JAVA - LINUX 명령어 실행하는 방법  (0) 2010.02.06
자바 메일 강의자료 Sendmail  (0) 2010.01.27
자바 특별한 Exception  (0) 2010.01.11
Class File Version Check  (0) 2009.12.18
메모리 릭에 대해 글쓰는중 ver1  (0) 2009.11.13
반응형
java.io.Broken pipe Exception

- java.net.SocketException: Connection reset by peer: socket write error
  원인: write 시 상대방 socket close 된 경우
    
- java.net.SocketException: Connection reset
  원인: read 시 상대방 socket close 된 경우

- java.io.IOException: Broken pipe
  원인: receiver에서 송신받은 데이터를 제때 처리하지 못하는 상황(네트워크가 느리거나 서버의 CPU가 max인 경우 등)에서 sender가 계속 보내는 경우


반응형

'Program > JAVA' 카테고리의 다른 글

JAVA - LINUX 명령어 실행하는 방법  (0) 2010.02.06
자바 메일 강의자료 Sendmail  (0) 2010.01.27
String Class 사용시 주의사항  (2) 2010.01.21
Class File Version Check  (0) 2009.12.18
메모리 릭에 대해 글쓰는중 ver1  (0) 2009.11.13
반응형

Class 파일의 버젼을 알아보는 방법에 대해 공부해 보도록 하겠다.
가끔 배치작업 또는 모듈제공등의 업무를 회사에서 할때에 이러한 케이스를 별도로 알아두고
작업하는것이 편하다.

예전에 보고 안봐서 잠시 까먹었었는데 이번기회에 제대로 정리를 해보도록 하겠다.

[서론]
java file -> class 파일의 확장자로 변경하게 되면 compiler가 compile이란 과정을 거치게 된다.
이떄 class file앞에 헤더를 붙이게 되는데 우리가 육안으로 알아보기 힘든 binary데이터와 hex데이터의  조합으로 이것저것 뒤섞여 버린다.이런놈의 버젼을 알아보는 방법에 대해 알아보도록 하자

[ 본론 ]
우선 아래 코드를 참조하자. developer들이 개발을 할때에 major한 부분을 개발하는 사람이 있고 minor한 버젼의 서브 프로젝트를 할떄가 있다. 따라서 하나의 배포판은 major버젼과 minor버젼의 합이라고 할수 있다. jdk 를 만드는 프로젝트 역시 sun사에서 2개로 나누어서 개발을 한다. 그 개발배포 버젼정보는 아래와 같다.

major  minor     version
45         3           1.0
45         3           1.1
46         0           1.2
47         0           1.3
48         0           1.4
49         0           1.5
50         0           1.6


위의 값은 버젼별로 major와 minor 버젼까지 알려준다.

그럼 class 파일을 하나 까보도록 하자 . hex 로 view를 해줄수 있는 울트라 에디터와 같은 좋은 툴이 있다면 class를 까볼수 있다.

해당 .class파일을 에디터로 열어보면 맨앞줄의 헤더정보는 아래와 같다.

0000000h : CA FE BA BE 00 00 00 30 00 BC 07 ~~~~

위 정보중에서 우리가 알아야 할정보는 영어 뒤에 값이다. HEX 값이기 때문에 저걸 10진수로 바꾸면
기본 헤더정보인 CA FE BA BE 뒤에 버젼정보가 온다는것을 알수가 있다.

00 00 | 00 30 이다. 마지막에 오는 30이 바로 version정보이다. 30은 hex코드이기 때문에 이것을 10진수로 변환하면 48이 된다. 이 48은 major 버젼의 정보가 되어 해당 파일은 1.4로 컴파일된 .class 파일인것을 알수 있다.

참조로 아래 표를 보자

00 00 | 00 30
minor   major  정보이다.

앞에 minor은 0이 되고 뒤에 major은 30을 10진수로 바꾼 48이 된다.

따라서 저놈은 버젼이 1.4인 것이다. 끝!!ㅋㅋㅋ

저걸 일일이 열어보려면 좀 짱난다.

아래 소스는 컴파일된 정보를 알아볼수 있도록 한 java 소스이다.

 import java.io.*;

public class ClassVersionChecker {
    public static void main(String[] args) throws IOException {
        for (int i = 0; i < args.length; i++)
            checkClassVersion(args[i]);
    }

    private static void checkClassVersion(String filename)
        throws IOException
    {
        DataInputStream in = new DataInputStream
         (new FileInputStream(filename));

        int magic = in.readInt();
        if(magic != 0xcafebabe) {
          System.out.println(filename + " is not a valid class!");;
        }
        int minor = in.readUnsignedShort();
        int major = in.readUnsignedShort();
        System.out.println(filename + ": " + major + " . " + minor);
        in.close();
    }
}




해당 소스를 보면 별거 없다. ㅋㅋ

실행하면 아래와 같은 결과가 나온다.

 > java ClassVersionChecker ClassVersionChecker.class
ClassVersionChecker.class: 49 . 0


이렇게 class 파일에 대한 정보를 알아 보는 방법에 대해서 몇자 끄적대보았다.

참조한 사이트 : http://www.rgagnon.com/javadetails/java-0544.html

이제 나이도 있는데

영어로 번역된 사이트를 참조하도록 하자. ㅋ

반응형

'Program > JAVA' 카테고리의 다른 글

JAVA - LINUX 명령어 실행하는 방법  (0) 2010.02.06
자바 메일 강의자료 Sendmail  (0) 2010.01.27
String Class 사용시 주의사항  (2) 2010.01.21
자바 특별한 Exception  (0) 2010.01.11
메모리 릭에 대해 글쓰는중 ver1  (0) 2009.11.13
반응형

메모리 릭에 대해서

인터넷에 끄적끄적 대어 알아낸 결과에 대해 간단히 적어본다.

이거 몰라서 차장님한테 욕먹음 ㅠㅠ;


[1] 메모리릭 이란 ? (정의를 알아야 뭐든안다)

 - 우선 말로 설명 하면 메모리 릭이란 한글로 메모리 "누수" 이다.
    누수란것은 어디론가 흘러간다는 뜻!!!! 일반적으로 개발자가 프로그램 작업시에 어떠한 객체 또는 변수에
    특정 메모리를 참조할수 있도록 할당한 다음에 해당 변수에대한 참조를 해지 핮지않고 프로그램을 종료한다.
    프로그램이 종료후에도  변수에 참조된 값은 해제가 되지 않거나, 참조 주소가 바뀌어서 영원히 해제가 되지
    않을때 생기는 문제이다.
    즉, 쉽게 말해서 gc가 처리해야할 대상에서 제외되는 것들이 생기는 현상을 말한다.
   
    말로하니깐 참 드럽게 어렵기도 하다.
    대충 소스를 보자 (랑이의 수도코드)

   

================================ A_Test.java ========================================
public class A_Test {
 public static void main(String[] args) {

  A_Test a = new A_Test(); // 요기서 a를 메모리 할당한다. 객체에 heap메모리의 주소값 참조함.
 
  B_Test b = new B_Test();

  b.rang(a); // call by reference로 a를 넘겨준다.
 
  a= null; // a에 참조된 객체값을 null로 하여 gc가 처리할수 있도록 해준다.
 }
}
======================================================================================

================================ B_Test.java ========================================

public class B_Test {
 private A_Test test = null;
 
 public void rang(A_Test a){
  test = a; // 내부에서 새로운 test라는 객체에 주소값을 복사해버린다.
 }
}

======================================================================================


위 소스를 보면 대~~~충 이해는 간다. B_Test 클래스에서 멤버변수에 새로운 주소값을 복사해 버린후에

test라는 객체는 주소값을 없애지 않고 날려버린다. 즉!!!!

test 라는 객체는 이제 오갈때 없는 heap영역안의 낙동강 오리알이 되어버린 것이다.

이런 오리알 들이 많이많이 쌓이면 heap라는 강물이 꽉차버린다. 그럼 어찌 되겠는가?

삐용삐용 장애발생이 되는것이다.

휴~~~~~~ 손가락 무지아프네..


[2] gc는 왜 처리를 못하는가?


자바에서 이론적으로 가비지 컬렉터 요놈이 알아서 ... 저러한 것들을 처리한다고 책에서 많이들 봐왔을것이다.
그럼 왜 이놈은 저런놈을 처리못하고 릭 상태로 해버리는것일까?

우선적으로 gc가 호출되어 메모리를 날려버리지 않는 대상에는 어떤놈이 있는지알아보자

- Http Session에 넣는 데이터..(세션 타임아웃 또는 invilidate 씨 까지 제외됨)
- Static 변수
- 서블릿 또는 jsp의 멤버변수 ( WAS 기동 후 최초 호출 시 인스턴스 화 되어 WAS가 내려 갈 때 까지 사라지지 않음 )


요3개는 나도 퍼왔다 . 모르는거니 퍼오는수밖에 ㅋㅋㅋ

보통 gc는 메모리를 알아서 관리해 주는 놈이라고 이론적으로 알고 있다.

하지만 gc는 신이아니다 . 개발자가 변수하나 설정 잘못해도 gc는 절대절대.... 그 해당 메모리를 해제하지못한다.
그렇기 때문에 개발자가 gc를 좀 도와줘야한다. 예를들어


Test test = new Test();
.
.
.
test = null;


이렇게 프로그램 좀 다 끝났다싶으면 null로 gc가 찾아내기 쉽게 바꿔주는것이바람직한 코딩법인것이다.


휴~~ 너무 많이썼더니 손가락 터지겠음.

다음시간에는 현재 메모리를 얼마나 잡아먹고 있고 / 메모리릭 이 일어나는 부분을 찾아내는 방법에 대해

툴 / 코딩법 등에 대해서 정리해서 올려보도록 하자!!!



- ps : 요거요거 엄청 빡세네 -.

                                                                        - 2009/11/15 신국의 화랑 성랑 랑이 씀 -

반응형

'Program > JAVA' 카테고리의 다른 글

JAVA - LINUX 명령어 실행하는 방법  (0) 2010.02.06
자바 메일 강의자료 Sendmail  (0) 2010.01.27
String Class 사용시 주의사항  (2) 2010.01.21
자바 특별한 Exception  (0) 2010.01.11
Class File Version Check  (0) 2009.12.18

+ Recent posts