ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • (2) 튜링팀과 람다팀, 자바
    튜링과 람다 2016. 3. 18. 14:43

    이 글은 월간 마크로소프트웨어 2015년 8월 자바 특집호에 기고한 글입니다. 원고가 길어서 두편으로 나눠 올립니다. 지금은 마소가 발행 중단되어 링크를 찾을 수 없습니다. 

     

     

    # Java의 탄생

     

    가상 머신 위에 애플리케이션을 실행하려는 사람들이 있었다. 마주한 환경은 녹녹치 않았다. 가상머신 위에 실행되는 Java는 1995년 제임스 고슬링(James Arthur Gosling)에의해 탄생했다. Java가 처음부터 지금의 모습은 아니었다. 20년을 보내며 많이 바뀌었다.

     

    Java가 태어날 당시 시대적 상황은 범용 언어인 C, C++이 대세였다. PC의 시대였고 Window가 시장을 거의 장악하고 있었다. Window에서 실행하는 소프트웨어를 개발하기 위해서는 Visual C++이나 비주얼 베이직로 개발해야 했다. 나머지 서버 사이드에서는 C 계열의 언어들이 대부분 이었다. Java가 당면한 시대적 요구는 크게 두가지가 있었다.

     

    첫 째는 객체 지향 언어다. 초창기에는 컴퓨터의 성능이 매우 낮았기 때문에 소스코드도 작았다. PC 시대가 열리면서 컴퓨터의 성능은 엄청나게 올라갔고 소프트웨어의 기능도 엄청나게 많아 졌다. 당연히 소스코드의 양도 크게 늘었고 늘어난 만큼 버그도 많이 발생했다. 버그 중에 가장 큰 골치 거리는 메모리 릭이었다. 얽혀 있는 소스 코드에서 릭을 잡기란 헤어진 여인의 마음을 잡기보다 어렵다. 커지는 소스코드를 더 잘 다루기 위한 방법으로 객체지향 개념이 떠올랐다. 지금 와서 보면 객체 지향 개념은 그 이전과는 확실히 소스코드를 다루기 편하다. 그 당시에 이론적으로 나와 있던 객체지향 개념은 현장에 적용 되고 있었다. C++은 객체 지향 개념을 갖고 있었으나 한계가 있었다. 이제 막 객체지향을 실험하는 단계이다 보니 혼동을 주는 개념들이 있었다. 지금은 이해가 안 가겠지만 C++가 처음 나왔을 땐 느리다고 쓰려고 하지 않았다.

     

    둘 째는 다양한 OS의 출현이다. 다양한 하드웨어가 개발 됐고 그에 맞는 운영체제가 올라 가다 보니 코드는 호환이 불가능했다. 하나의 코드를 만들어 다양한 환경에서 실행하려는 아이디어가 모색 됐다.

     

    이 두가지는 소프트웨어의 생산성을 떨어트리는 주요한 원인이었다. 이 문제를 해결한 것이 바로 Java다. 코드의 문법은 C를 계승하면서 비슷한 기능의 문법을 통합해 간단한 문법으로 정의했다. Java는 애초의 취지와는 다르게 다른 데서 인기를 얻었다. 가전이나 셋탑에 적용하려 했지만 실패했고 인터넷을 만나면서 Java는 새로운 기회를 잡았다. 마침 Java의 장점이 인터넷과 잘 맞았다. 인터넷을 만난 Java는 훨훨 날았다. html로는 동적인 기능을 구현할 수 없었기 때문에 Java가 Web에서 대안으로 떠올랐다. 그 당시 html은 지금의 모습과 많이 달랐고 정말 Markup Language였다. 채팅 같은 건 구현이 불가능했다. 그 당시에 유행하던 채팅 사이트는 대부분 Java Applet을 사용해 개발됐다.

     

    내가 처음 본 Java는 1.2 버전이었다. 그 이전까지 없었던 새로운 개념의 언어였다. 특히, 개발자가 직접 메모리를 관리할 필요가 없다. 동일한 바이너리가 윈도우와 리눅스에서도 실행이 된다. 게다가 문법도 간단했다. 그러나 한계도 있었다. 부족한 라이브러리와 느린 컴파일러, 무엇보다 느린 성능이 문제였다. 초기에 만들어진 이미지 때문에 Java는 느리다는 오명을 얻었다.

     

    C#, ActionScript 같은 VM 기반 언어들이 등장했다. 이런 언어 앞에 Java가 있었다. Java는 VM 기반 언어를 대중화 시켰다. VM은 성능 문제가 있었다. Java가 성능을 끈질기게 개션하면서 가능성이 아니라 현실로 입증했다. 지금 사용 빈도가 높은 언어들은 대부분 VM 기반 언어다. 언제나 그렇지만 처음 시도는 늘 저항을 동반한다. 느린 성능에 부디쳐 Java가 개선을 포기했다면 우리는 지금도 메모리를 직접 관리하며 포인터로 골머리를 썩고 있을 지도 모른다.

     

    현재의 Java 모습을 생각하면 초기의 이런 모습은 이상할 수 있다. 격세지감이다. 지금 Java는 참 훌륭하다. 이젠 대세를 넘어 주류다. 경쟁자들도 Java를 따라하거나 유사한 방식을 체택한다. 객체 지향 언어의 대중화에 큰 기여를 했다. 물론 Java 이전에도 객체 지향 언어는 있었다. 그러나 산업적으로 의미가 없었다. 돈을 벌 수 있는 프로젝트에 쓸 수 있어야 개발자가 양성되고 기술이 발전하는 선순환이 일어난다. Java는 이 지점에서 혁혁한 공로가 있다.



    # Java의 시련

     

    Java는 느렸다. 지금은 느리다는 말이 낯설다. 초기부터 꽤 오래 동안 Java를 따라 다니며 괴롭혔던 말이다. 실제로 사람들이 느끼는 속도가 느렸다. 못 써먹을 정도는 아니 였다. 느려도 신기한 플랫폼을 쓰는 쏠쏠한 재미가 있었다. 소프트웨어의 초기 버전은 일단 구현에 집중하다 보니 성능은 떨어지는 경우가 많다. Java도 마찬가지였다. 느리다는 오명에도 불구하고 Java는 인기를 얻었다. 느린 성능이 Java의 성공을 막지는 못 했다.

     

    중요한 성공 요인은 인터넷 시대에 Java의 경쟁자가 없었기 때문이다. Java는 인터넷 시대가 열리면서 빠르게 변신해 나갔고 여러 기업들이 참여 하면서 생태계가 커졌다. 어떻게 보면 Java가 가질 수밖에 없는 숙명일지도 모른다. VM을 처음 개발했으니 말이다. 근본적으로 네이티브 보다 VM은 느릴 수 밖에 없기 때문이다. 이런 걸 처음 시작했으니 가장 맨 앞에서 구박을 받을 수밖에 없다. Java가 오명을 어떻게 극복했는 지 보자.

     

    크게 내적 원인과 외적 원인 두가지로 볼 수 있다. Java는 숱한 구박에도 끊임 없이 착착 해결해 나갔다. 물론 중간에 시행착오도 있었다. 내적 원인은 Java 가상 머신이 느렸다. Java 자체가 가지고 있는 근원적 한계다. VM 자체도 하나의 애플리케이션이다. Java는 VM위에 다시 애플리케이션이 올라 가다 보니 Native Code보다 느릴 수밖에 없다.

     

    외적 원인은 컴퓨터가 느렸다. 90년대 후반의 컴퓨터는 지금 스마트폰 보다도 떨어지는 CPU와 RAM을 갖고 있었다. 1999년 CPU는 싱글 코어 500Mhz, RAM은 64M를 갓 넘어 가고 있었다. 3D 그래픽 게임이 지금 휴대폰에서도 팡팡 돌아가지만 90년대 후반에야 슬슬 등장했고 그래픽 카드의 보급도 이때쯤 이었다. 가상 머신이 원활히 실행될 수 있는 상황은 아니었다.

     

    나는 체감상 Java의 성능이 크게 두 가지 지점에서 향상 됐다고 본다.

     

    먼저 개선이 된 것은 입출력 라이브러다. 애플리케이션이 보통 느려지는 원인 중에 하나가 스토리지나 네트웍의 병목 현상이다. CPU에서 아무리 빨리 연산을 해도 HDD에 저장에서 느리면 전체 성능은 느린 것으로 결론이 난다. Java 1.4 에 NIO(New IO)라이브러리가 추가 되면서 획기적으로 개선됐다. 특히 Java는 네트웍이나 서버에서 강점이 있었기 때문에 NIO의 탄생은 Java에게 날개를 단 겪이다. Netty와 Apache Mina는 NIO로 개발된 대표적 오픈소스다. 게다가 한국 개발자의 작품이다.

     

    NIO는 비동기식 소켓을 지원했다. 전통적 소켓은 read에서 대기를 한다. 반면에 비동기식 소켓은 대기 하지 않고 페킷이 도달하면 invoke된다. 이 작은 차이는 서버의 성능에 큰 영향을 준다. Thread의 사용을 대폭 줄일 수 있다. Thread는 굉장히 비싼 컴퓨팅 자원이다. 요즘 서버는 대체로 비동기 방식으로 구현을 한다. 직접 구현하기 보다는 Netty 같은 좋은 오픈소스를 사용하면 고급 기능을 쉽게 쓸 수 있다.

     

    두번쩨로, 가장 Java가 약한 부분이 그래픽이었다. 클라이언트 애플리케이션을 개발하는데 GUI는 필수다. 특히 화면에 표시되는 느낌은 유저가 직접 눈으로 확인을 하는 지점이라 더욱 민감하다. 다른 성능이 다 좋아졌더라도 그래픽에서 빠지면 소용 없다. 유저는 그냥 느리다고 느낀다. 불행히도 Java는 가장 이 지점에 신경을 안 썼다. 클라이언트는 MS의 Window가 장악하고 있었기 때문에 들어갈 틈이 매우 좁았다. 아니 거의 없었다. 지금은 스마트폰때문에 시장이 분화 되어 있지만 PC의 시대엔 MS는 제국이었다. 타의건 자의건 Java는 그래픽에 가장 약했다. 그래픽에 신경을 쓰게 된 계기는 외부로부터 왔다. IBM의 Eclipse가 인기를 끌면서 새로운 방식으로 GUI문제를 해결했다. 모든 OS의 네이티브 GUI를 JNI로 바이딩해서 Java로 올렸다. 당연히 스윙보다 빨랐다. IDE 만큼 무거운 애플리케이션을 개발할 정도면 GUI로서 가능성은 충분했다.

     

    Java Swing은 그래픽의 가장 밑단 부터 모두 Java로 구현됐다. 자부심은 있었겠지만 경기엔 졌다. 아무도 안 썼다. 쓰는 사람이 있었지만 소수였다. 성능이 크게 좌우 안 하는 분야이거나, Java를 너무 사랑하거나, Java 개발자밖에 없거나 대략 이 정도 상황에서 Swing을 사용했다. Sun의 Forte IDE는 Java로 만들었는데 정말 무거웠다. 그 당시 내 컴퓨터가 나빠서 그럴 수도 있지만 실행을 시키고 안 뜨길래 잠시 화장실을 갔다 왔다. 모니터에서 먼가 나타나기 시작했다. Forte IDE였다. 개발을 커녕 구경도 못 하는 상황이다. 반면에 같은 PC에서 Eclipse는 매우 매끄럽게 실행 됐다. 물론 코딩할 때도 문제 없었다.

     

    Java 6는 큰 변신을 했다. 사람들은 이 변화를 잘 알지 못 한다. 몰래 변경한 것도 아니다. 스윙으로 개발된 애플리케이션을 쓰지 않기 때문에 성능이 올라간 것을 알아 채기 어려운 환경이었다. 난 이 변경이 Java의 중요한 발전이라고 본다. Java의 그래픽에 OpenGL 파이프라인을 사용했다.  하드웨어 가속을 받으니 당연히 빨라졌다. 그 이전의 스윙과 체감 속도는 완전 달랐다. 정말 쓸 만 해졌다. 당연히 스윙으로 만든 NetBeans IDE는 쾌적해졌다. Java 6는 2006년 12월에 릴리즈 됐다. 이 시기에 컴퓨터 성능이 많이 올라갔고 그래픽 카드가 대중화 되면서 Java에게 이로운 상황으로 전개됐다. 게다가 JVM 차체도 많이 개선됐다. 더 이상 JVM은 가상 기계 수준이 아니다.

     

     

    다음편에 계속

    (3)튜링팀과 람다팀, 자바

     

     

    '튜링과 람다' 카테고리의 다른 글

    (3) 튜링팀과 람다팀, 자바  (0) 2016.03.18
    (1) 튜링팀과 람다팀, 자바  (0) 2016.03.18

    댓글

(c)민들레