2015년 12월 10일 목요일

모던 자바의 역습(2) 자바를 둘러싼 진실 혹은 거짓말

이번 포스팅은 김대우 님(http://lekdw.blogspot.kr/)과 함께 진행한 동명의 웨비너의 발표 내용에 바탕을 두고 작성되었습니다. 세상에 나온지 어느덧 20년. 오랜동안 프로그래밍 언어의 절대 강자로서 세상을 호령하던 자바를 둘러싼 진실 혹은 거짓말 그리고 과거와 미래에 대하여 알아봅니다.

스크롤의 압박을 피하기 위해 이번 포스팅은 다섯 파트로 나누어 연재합니다.


모던 자바의 역습 

2. 자바를 둘러싼 진실 혹은 거짓말

자바는 오래된 언어이고 여러 영역에 걸쳐 쓰이다 보니 다양한 모습을 지니고 있습니다. 그러다 보니 언어 자체에 대한 선입견이 많이 쌓인 것도 사실입니다. 일반적으로 자바에 대해 개발자들이 가지고 있는 선입견은 다음과 같습니다.

자바의 성능

자바의 성능에 대한 의구심은 JVM의 최적화가 아직 덜 된 1.4 이전의 이미지가 선입견으로 굳어진 부분이 있습니다. 자바는 새 버전을 발표할 때마다 JVM의 성능 향상을 릴리즈 노트에 꼭 적어 놓고 있습니다. 결과적으로 많은 성능 개선이 이뤄져왔습니다. 다음의 그래프는 현 시점에서 자바가 여러 언어 사이에서 차지하는 성능에 대한 객관적인 지표로 참고할 만합니다.


위 그래프는 여러 언어들에 대하여 10종류의 로직을 벤치마크한 결과값을 나타냅니다. 자바의 경우 C/ C++에는 미치지 못하지만 비교적 상위권에 속한다는 사실을 알 수 있습니다. 여기서 한 가지 주의해야 할 점은, 이 벤치마크 결과는 순수하게 로직이 움직인 시간 만을 측정한 것으로 실행 파일이 메모리에 로딩되는 시간은 포함되지 않았다는 점 입니다. 자바의 경우 실행에 필요한 바이트코드 로딩시간  이외에도 JVM과 라이브러리가 메모리에 로딩되는 시간이 추가로 필요한데 이러한 초기 기동 시간이 오래걸리는 것이 자바가 느리다는 선입견에 한몫하지 않았나 합니다.

NIO의 Direct ByteBuffer

자바 1.4에서 추가된 NIO는 자바 7에서 2.0으로 버전업하며 더 강력한 기능을 선보이고 있습니다. javamex.com에서 실시한 벤치마크 결과에 따르면 NIO에서 추가된 direct ByteBuffer는 일반적인 ByteBuffer에 비해 평균적으로 20% 정도의 성능 개선을 보이는데 버퍼 크기가 커질수록 성능의 차이도 크게 벌어집니다.
NIO direct ByteBuffer벤치마크 결과



Netty PooledMemory를 이용한 고속 애플리케이션 구현

최근 성능에 목말라 하는 많은 자바프로그래머들로부터 주목받고 있는것이 바로 네티(Netty) 프레임워크(netty.io) 입니다. 이희승 님이 오픈소스화하여 발전된 Netty 프레임워크는 성능 향상을 위한 IO 관련 API부터 동시성 구현에 이르기까지 고성능에 구현하기 편하게 잘 디자인된 API 세트를 제공하고 있습니다. 네티의 여러 API 중에서도 특히 PooledMemory라 불리우는 buffer pool은 자바 기본 API에 비해 강력한 성능과 메모리 관리 효율을 자랑합니다.

간편해진 JVM 튜닝

초기 자바 버전에서 JVM 튜닝은 자바 애플리케이션, 특히 서버 애플리케이션에 있어서 안정성과 성능에 직접적인 영향을 끼치는 중요한 요소였습니다. 하지만 JVM 튜닝에 제공되는 옵션들은 JVM의 내부 동작구조에 대한 이해가 없이는 다루기가 어려웠고 최적값을 구하기 위해 설정값을 변경해가며 모니터링해야 하는 불편함이 있었습니다. 오늘날 자바 서버 애플리케이션에 있어서 JVM 튜닝은 다음의 네 가지 옵션 지정만으로도 대부분의 경우 무난히 작동합니다. 다만 대량의 IO가 발생하여 더 최적화된 가비지 콜렉션을 수행해야 하는 경우에는 사용하는 라이브러리의 특성과 내부적인 처리 방식에 따라 가비지 콜렉션 옵션을 적절히 지정해줘야만 합니다.    

  • -server : 서버 모드 기동. JVM을 장시간 실행해야 하는 서버 애플리케이션이 빠르고 안정적으로 실행될 수 있도록 최적화합니다. 참고로 client 모드의 경우 JVM의 빠른 기동과 더 적은 메모리를 사용하도록 조절됩니다.
  • -d64 : 64비트 JVM에서만 사용 가능한 모드로 JVM이 64비트 모드로 작동될 수 있도록 합니다. 64비트 어드레싱을 사용하므로 32비트 JVM의 상한선인 2기가 바이트를 넘어선 대용량의 메모리를 사용할 수 있습니다.
  • -Xms 과 -Xmx : 메모리 할당 풀의 하한선(Xms)과 상한선(Xmx)을 지정합니다. 상한선의 경우 너무 작게 잡으면 OutOfMemoryError가 일어날 수 있고, 너무 클 경우는 FullGC 시에 많은 시간이 소요되게 되므로 적절한 수치를 지정하는 것이 중요합니다.

언어별 생산성 비교

처음 등장할 당시에는 C/C++ 그리고 아직 엔터프라이즈 영역에서 무시 못할  세력을 가지고 있던 Cobol 언어에 비해 높은 생산성을 자랑하던 자바였지만 이후 등장한 C#이나 VB.net, 파이썬, 루비 등의 언어와 비교하여 다소 생산성이 떨어진다는 평가를 받게 됩니다.
하지만 프로그래머를 위한 웹진으로 유명한 Dr.Dobbs의 조사 결과에 의하면 전체 언어 중에서도 비교적 상위권(3위)에 속하는 생산성을 보여주고 있습니다.


언어명
기능포인트FunctionPoint를 구현하는데 소요되는 시간
ASP*
6.1
Visual Basic
8.5
Java
10.6
SQL
10.8
C++
12.4
C
13.0
C#
15.5
PL/1
14.2
COBOL
16.8
ABAP
19.9
언어별 생산성 비교

다만, 이 수치는 단순히 언어의 문법적 기능적 차이에서 오는 생산성 뿐만이 아니라, 개발 툴셋, 라이브러리와 레퍼런스의 풍부함, 그리고 해당 언어가 자주 사용되는 도메인 영역의 특성이 종합적으로 영향을 끼친다고 보아야 할 것입니다.

자바 기반 초고속 개발 프레임워크 - Vaadin

오늘날 자바를 있게 한 일등공신을 꼽으라면 인터넷을 꼽을 수 있습니다. 하지만 지금은 사정이 다릅니다. 루비온 레이즈(RoR, Ruby on Rails)가 선보인 웹 개발 스타일은 개발 속도와 편리함이라는 측면에서 엄청난 혁신을 가져온 것 입니다. 오늘날 자바를 이용한 웹 개발의 대세는 아직까지 스프링이 중심이지만, 아카(Akka) 라이브러리를 이용해 actor 모델을 구현한 플레이(Play) 프레임워크이나  지금 소개하고자 하는 바딘(Vaadin)의 경우 RoR의 개발 철학에 직접적으로 영향을 받아 발전시킨 프레임워크이라 할 수 있습니다.


Screen Shot 2015-07-24 at 7.31.55 AM.png
HTML, CSS, Javascript등 웹 UI 요소들을 서버사이드 자바 코드로 제어할 수 있게 해 주는 프레임 워크 - Vaadin


Vaadin은 웹 개발에 있어서 갈수록 중요도를 더해가고 있는 프론트엔드, 특히 자바스크립트와 CSS에 대한 부담을 덜어주기 위해 개발된 경량 프레임워크입니다. 백엔드 뿐만이 아니라 프론트엔드까지 모두 자바만으로 개발할 수 있도로 설계되어 있어 자바스크립트뿐만이 아니라 HTML까지도 자바에서 정의 가능한, 자바 개발자에게 있어서는 그야말로 환상적인 프레임워크라 할 수 있습니다.

vaadin의 아키텍처
출처 : dev.vaadin.com


자바의 언어 생태계

오늘날의 자바가 강력한 위상을 가지게 된 데에는 자바 플랫폼 이외에도 개발 환경, 라이브러리, 튜토리얼, 패키지 관리 시스템 등 자바를 둘러싼 거대한 언어 생태계를 빼 놓고는 이야기할 수 없습니다. 특히 오늘날까지 자바의 통합개발 환경으로 널리 사랑받고 있는 이크립스의 경우 높은 완성도에도 불구하고 무료인데다가 기능 확장이 자유롭도록 OSGi 기반의 플러그인 시스템을 갖추고 있어 단순한 툴을 넘어 플랫폼에 가까운 지위를 지니고 있습니다. 여러 개발 언어들이 각축전을 벌이고 있어 가히 언어의 춘추전국시대라 불리우기에 손색이 없는 요즘 시대에도 자바는 거의 모든 미들웨어나 플랫폼, 클라우드 서비스에게 있어서 최우선 지원 대상이 되고 있어 어떠한 형태의 개발을 진행하더라도 충분히 필요한 리소스와 레퍼런스를 지원받을 수 있습니다.

자바의 거대한 언어 생태계
출처 : http://readwrite.com/2011/01/24/the-java-ecosystem-infographic