Whiteship's Note

클래스파일 보기

Java : 2009.07.20 17:10


javap -c 클래스파일명(확장자빼고)

예) javap -c Sample

이클립스에서 보려면 네비게이터 뷰에서 타겟 폴더로 이동해서 보시면 되죠.

public class JavaPSample {

    public void test(){
        String a = "a";
        String b = "b";
        String c = a + b;
        String d = "ab";
    }
   
}

이 녀석을 컴파일 한 클래스의 모습니다.

// Compiled from JavaPSample.java (version 1.6 : 50.0, super bit)
public class sandbox.JavaPSample {
 
  // Method descriptor #6 ()V
  // Stack: 1, Locals: 1
  public JavaPSample();
    0  aload_0 [this]
    1  invokespecial java.lang.Object() [8]
    4  return
      Line numbers:
        [pc: 0, line: 3]
      Local variable table:
        [pc: 0, pc: 5] local: this index: 0 type: sandbox.JavaPSample
 
  // Method descriptor #6 ()V
  // Stack: 3, Locals: 5
  public void test();
     0  ldc <String "a"> [16]
     2  astore_1 [a]
     3  ldc <String "b"> [18]
     5  astore_2 [b]
     6  new java.lang.StringBuilder [20]
     9  dup
    10  aload_1 [a]
    11  invokestatic java.lang.String.valueOf(java.lang.Object) : java.lang.String [22]
    14  invokespecial java.lang.StringBuilder(java.lang.String) [28]
    17  aload_2 [b]
    18  invokevirtual java.lang.StringBuilder.append(java.lang.String) : java.lang.StringBuilder [31]
    21  invokevirtual java.lang.StringBuilder.toString() : java.lang.String [35]
    24  astore_3 [c]
    25  ldc <String "ab"> [39]
    27  astore 4 [d]
    29  return
      Line numbers:
        [pc: 0, line: 6]
        [pc: 3, line: 7]
        [pc: 6, line: 8]
        [pc: 25, line: 9]
        [pc: 29, line: 10]
      Local variable table:
        [pc: 0, pc: 30] local: this index: 0 type: sandbox.JavaPSample
        [pc: 3, pc: 30] local: a index: 1 type: java.lang.String
        [pc: 6, pc: 30] local: b index: 2 type: java.lang.String
        [pc: 25, pc: 30] local: c index: 3 type: java.lang.String
        [pc: 29, pc: 30] local: d index: 4 type: java.lang.String
}

중간에 보시면 StringBuilder의 append를 사용하는 모습을 볼 수 있는데, 한 줄에있는 + 연산은 StringBuilder의 append를 이용함을 알 수 있습니다. 따라서, 연달아 append를 할 경우에는 굳이 StringBuilder를 사용할 필요 없이 + 연산만으로도 충분할 것 같습니다.

앞에 숫자들은 라인 넘버인것 같고, 그 다음 문자열들(idc, astore, aload, invokevirtual, invokestatic, invokespecial 등)은 JVM 명령어라고 합니다.

ASM, BECL, Javassist 이 세 가지가 대표적인 바이트 코드 조작 라이브러리 인데, CGLIB은 이 중에서 ASM을 사용하고, AspectJ는 BECL을 사용 한다네요.

음.. 기본은 항상 다져야 되나 봅니다. 모르는 것도 많고 예전에 본것도 다 까먹네요.
스펙이랑 자바퍼즐러라도 볼까봐요.
top

  1. Favicon of http://blog.lckymn.com BlogIcon Kevin 2009.07.20 21:19 PERM. MOD/DEL REPLY

    Bytecode에 관심이 있으시다면, Eclipse용 plugin인 Bytecode Outline plugin for Eclipse
    한번 써보세요. :) (아... 이미 쓰고 계시려나?)
    http://andrei.gmxhome.de/bytecode/index.html

    전 Performance 검사라던가, "내가 이거 제대로 하고 있는거야?" 등을
    확인하기 위해 즐겨 쓰고 있습니다. :)

    String의 경우
    String text = "something" + "something else";
    하면 Java Compiler 가 똑똑하기 때문에 합쳐서
    "somethingsomething else" 을 만들어 버립니다. :)

    근데 variable을 추가하면 StringBuilder로 바뀌져.
    String a = "test"
    String text = "something" + "blah" + a + "test" + "something else";
    이렇게 되면, "somethingblah" 까지는 하나로 합쳐서
    StringBuilder 생성하면서 Constructor 파라메터로 넘기지만,
    일단 variable이 등장하면 그 뒤는 다 따로 append됩니다.
    즉, a뒤쪽에 있는 "test" 와 "something else" 부분도 따로 append 되는거죠.

    String test = "a";
    test += "b";
    test += "c";
    이거 하면 추가시마다 메모리가 각각 새로 할당되서 속도가 느려진다는건
    다 아는데, 실제로 compile된 bytecode에서는
    +로 추가 할때마다 StringBuilder가 새로 생성되면서
    글자 추가하고 toString()으로 재할당 하더라구요.
    즉, builder가 두번이나 생성되는거죠.


    Spring이나 Hibernate 같은 frameworks 쓰면 쓸수록 느껴지는게
    나한테 필요한 혹은 내가 만드는 application에 딱맞는 framework를
    개발해서 쓰고 싶다는 겁니다.

    Spring이나 Hibernate가 충분히 편하고 좋긴 하지만,
    저한테 딱 맞는 기능이 없다거나, 어떤건 필요도 없는데
    들어있어서 덩치만 늘어난거 같은 느낌이 든다거나...
    여러가지 일반적인 혹은 흔한 상황을 두루 만족시켜주기 위해서
    당연한 거겠죠.

    그러다 보니 일반적인 용도보다 제게 필요한 녀석을
    하나 만들고 싶은 생각이 드네요.
    그냥 하나라기 보다 어플 종류에 따라 그때그때 변형해서
    쓸수 있도록 해야겠죠.

    암튼 그래서 ASM 좀 사용해 보려고 하는데, 현실은...

    바빠서, 댓글에 적어놓은 String 관련 내용 포스팅도
    못하고... ㅠ_ㅠ (이 말을 4월에도 하고 아직도... ㅡ_ㅡ; )

    Favicon of https://whiteship.tistory.com BlogIcon 기선 2009.07.20 23:27 신고 PERM MOD/DEL

    캬... 이번에도 어김없이 포스팅급 댓글을 주셨네요.ㅎㅎ

    + 연산에 변수가 껴있는 것과 그렇치 않은 것과 차이가 있었군요.

    사실 전 아직까지도 바이트코드엔 별로 관심이 없습니다. 오늘도 톱님께서 위에 내용을 알려주지 않았다면 아마.. 평생 관심을 끄고 살았을지도 모르겠네요.

    조금 들어보고 나니 바이트코드를 직접 조작해서 제니퍼같은 모니터링 툴도 만들고 AspectJ도 그렇게 동작한다고 하니.. 중요한 걸 외면하고 있었단 느낌이 들더라구요.

    흠.. 스프링, 하이네이트. 넘 어려워요. @_@

  2. Favicon of http://blog.lckymn.com BlogIcon Kevin 2009.07.21 00:43 PERM. MOD/DEL REPLY

    저도 바이트코드에 크게 관심이 있었던건 아니구요,
    작년초쯤인가에 스테판이 프로그래밍을 바이트코드 조작해서 한다고 하길래
    아... 프레임워크 만들자면 속도등을 고려해서 그렇기도 하겠구나 라고만
    생각한거 정도에다 말씀드린 성능 검사등등을 위해서 보는 정도였는데
    최근에 "내가 만든 framework가 필요해!" 라는 생각을
    하고 부터 관심'만' 가지고 있습니다. :)
    아... 어서 빨리 ASM을 익혀서...

    근데 생각해 보니 일단 시작은 reflection만 가지고 해도 될것 같아요.
    (가 아니라 이미 그렇게 해서 대충 쓰고 있었네요... @_@; )
    어차피 이것도 필요할수 있는게,
    Android같이 bytecode 조작을 할수없는 환경에서는
    어쩔수 없이 일반 reflection을 써야 할테니,
    Google Guice가 그래서 2.0버전에서는 bytecode 조작 못하는 환경을 위해
    AOP분리한 버전을 따로 내놨죠.

    근데, 스프링과 하이버네이트 잘 쓰는분이
    어렵다고 하시다니요... :)
    역시 겸손하시군요.

    Favicon of https://whiteship.tistory.com BlogIcon 기선 2009.07.21 09:58 신고 PERM MOD/DEL

    넹 저도 리플렉션은 간간히 이용하고 있어요.
    우와.. 구글 쥬스와 안드로이드까지 @_@
    관심갖으시는 기술 영역이 정말 넓고 깊으신듯해요.

    댓글로 많이 배우고 있습니다.
    감사합니다. :)

    스프링 하이버는 이제 조금 유저로써 익숙해진 것 뿐이지 그리 깊게 알진 못한답니다.

  3. Favicon of http://blog.lckymn.com BlogIcon Kevin 2009.07.22 21:24 PERM. MOD/DEL REPLY

    헉! 절대 아닙니다...@_@;;;

    쟁쟁한 제 친구들에 비하면 새발의 피죠...
    http://www.ryanheise.com/tetris/tetris_artificial_intelligence.html
    제 친구는 구글 페이지랭크 알고리즘을 이용해서 테트리스를 가장 효과적으로
    플레이하는 인공지능 프로그램을 개발 했더군요.
    중간에 watch replay 해서 한번 보세요. :)
    웹브라우저용 Java Plugin이 필요합니다.

Write a comment.




: 1 : ··· : 447 : 448 : 449 : 450 : 451 : 452 : 453 : 454 : 455 : ··· : 2638 :