어제 저녁에 "자바 성능을 결정짓는 코딩 습관과 튜닝 이야기" 저자의 세미나가 있었습니다.
기본적인 내용들이지만 놓치기 쉬운 좋은 내용들이 있어 공유합니다.

시스템 튜닝의 궁극적인 목적은 운영 서버 갯수를 줄이는 것입니다.
국내 N포털 사이트의 서버는 비공식적으로 몇만개가 되는 것으로 알려져 있고,
구글은 서버 전력 공급을 직접적으로 하기 위해 발전소를 짓는다고 공언했죠.(대단한 사람들입니다.)
튜닝대상에는 DB, IO, WAS, NETWORK 등 많이 있겠지만, 개발자의 작은 습관으로 성능을 향상할 수 있는 몇가지 팁을 소개드립니다.

1. 문자열 연결에는 StringBuffer 의 사용.
문자열을 연결할때 String 클래스를 사용하여 다음과 같이 많이 사용합니다.
String str = "Hello" + " JAVA" + " World";
이렇게 코딩할 경우 Hello JAVA 라는 새로운 임시객체가 생성되고, 또 그 임시객체와 World 라는 문자열을 묶어 새로운 임시객체가 생성됩니다.
따라서 GC 대상이 되는 객체가 늘어납니다.
String 외에 문자열 관련 클래스는 StringBuffer 와 StringBuilder 가 있는데, 둘의 차이는 Thread Safe 한가의 차이입니다. 따라서 Thread Safe를 고려해야 할때는 StringBuffer를 사용하고, 아닌 경우에는 StringBuilder를 사용하는 것이 성능 향상에 좋습니다.
*** 사용예.
StringBuffer sbQuery = new StringBuffer();
sbQuery.append("SELECT NAME, ADDR, TEL ");
sbQuery.append("  FROM TB_ADDR ");
이번 프로젝트의 소스코드중에 특히 쿼리문에서 String 클래스를 통한 문자열 연결이 많았는데, 이러한 레거시 코드를 보면 모두 고치도록 합시다.^^

2. for, while, do ~ while 등 루프문에서의 검증값.
벡터에 들어있는 데이터를 모두 출력한다고 할때
Vector vt = new Vector();
vt.addElement("Hello");
vt.addElement("JAVA");
vt.addElement("World");
String msg = "";
for (int i = 0; i < vt.size(); i++) {
  msg = (String)vt.elementAt(i);
  System.out.println(msg);
}
이와 같이 사용하게 되는데, for 루프의 검증값 vt.size() 가 매번 호출되어 성능 저하를 가져옵니다.
따라서 루프의 검증값은 별도의 변수를 만들어 사용하는 것이 성능 향상에 좋습니다.
*** 사용예
int nVtSize = vt.size();
for (int i = 0; i < nVtSize; i++) {
  msg = (String)vt.elementAt(i);
  System.out.println(msg);
}

3. System.out.println(); 사용 자제
IO는 시스템에서 리소스를 가장 많이 먹는 것중 하나죠.
디버깅을 위해 System.out.println("Value a:" + a + "/ Value b:" + b); 이렇게 사용하실텐데, 이때 문자열 결합에 따른 비용까지 엄청나죠.
운영 서버에 반영하기 전에 반드시 삭제하시기 바랍니다.

4. Statement와 PreparedStatement
Statement는 매번 쿼리 실행시마다 쿼리를 컴파일을 하고,
PreparedStatement는 한번 컴파일 해놓을 것을 계속 사용합니다.
따라서 성능향상에는 PreparedStatement를 사용하는 것이 좋습니다.

Posted by 창신다이
interface II {
  public abstract void method(); 
  //interface에서 멤버 변수들은 디폴트로 public static final(상수선언) 
  //멤버 함수들은 디폴트로 public abstract
}

class CB implements II{
 //interface를 상속 받은 클래스는 상속 받은 interface의 모든 메쏘드를 구현해야함
 public void method() { 
  System.out.println("method in CB");
 }
}

class CC implements II {
 public void method() {
  System.out.println("method in CC");
 }
}

//클래스 CA는  팩토리 클래스. 인자에 따라 II를 구현한 클래스의 method()를 호출하게됨
//virtual function invocation
class CA {
 public void method(II i) {
  i.method();
 }
}

class CExample {
 public static void main(String[] args) {
  CA oa = new CA();
  oa.method(new CB());
  oa.method(new CC());  
 }
}

<Virtual Method Invocation의 원리>
1. Compile Time Type : 부모의 메모스를 호출(II의 method 호출)
2. Runtime Type : 자식의 메소드가 실행(II를 상속받아서 구현한 CB의 method 혹은 CC의 method 호출) "상속관계의 오버라이딩된 메소드에서만 발생하는 원리"

Posted by 창신다이

BLOG main image
오랫동안 꿈을 그리는 사람은 마침내 그 꿈을 닮아 간다. -앙드레 말로- by 창신다이

공지사항

카테고리

분류 전체보기 (248)
공장이야기 (115)
C/C++ 이라도 잘 하자 (23)
엑셀의달인 (8)
윈도우즈프로그래밍 (16)
Unix (3)
DB실전 (4)
MAC OS (3)
모바일 (18)
정보보호 (4)
보안가이드 (0)
WEB (2)
JAVA도 기본은... (2)
기술사 (0)
휴지통 (29)
Education (30)
회사이야기 (19)
일상 (73)

최근에 올라온 글

최근에 달린 댓글

최근에 받은 트랙백

Total :
Today : Yesterday :