아 최근에 나눔글꼴 쓰고 있는데. 좋다..
글꼴의 스크린 샷은 요기를 참고하세요.. ^^
NanumGothicCoding_Setup-2.0.exe
월: 2010 1월
자바 메모리 구조
MemoryUsage 클래스를 통해서 메모리에 대한 정보를 모니터링 해보면 아래의 결과를 확인할 수 있다.
USAGE(Code Cache) init = 163840(160K) used = 535168(522K) committed = 557056(544K) max = 33554432(32768K)
USAGE(Eden Space) init = 917504(896K) used = 807560(788K) committed = 917504(896K) max = 4194304(4096K)
USAGE(Survivor Space) init = 65536(64K) used = 0(0K) committed = 65536(64K) max = 458752(448K)
USAGE(Tenured Gen) init = 4194304(4096K) used = 0(0K) committed = 4194304(4096K) max = 61997056(60544K)
USAGE(Perm Gen) init = 12582912(12288K) used = 699408(683K) committed = 12582912(12288K) max = 67108864(65536K)
USAGE(Perm Gen [shared-ro]) init = 8388608(8192K) used = 5344032(5218K) committed = 8388608(8192K) max = 8388608(8192K)
USAGE(Perm Gen [shared-rw]) init = 12582912(12288K) used = 6771000(6612K) committed = 12582912(12288K) max = 12582912(12288K)
위 내용을 보면, 대략 7개의 메모리 영역이 있고, 메모리 영역에 대해서 찾아보니 어느 성능관련 엔지니어의 블로그에 아래와 같은 설명이 있다. ^^
Code Cache: contains memory used for compilation and storage of native code
Eden Space: pool from which memory is initially allocated for most objects
Survivor Space: pool containing objects that have survived Eden space garbage collection
Tenured Gen: pool containing long-lived objects
Perm Gen: contains reflective data of the JVM itself, including class and memory objects
Perm Gen [shared-ro]: read-only reflective data
Perm Gen [shared-rw]: read-write reflective data
convert nanoseconds to seconds or milliseconds
// second long second = TimeUnit.SECONDS.convert(nanoSeconds, TimeUnit.NANOSECONDS); // millisecond long second = TimeUnit.MILLISECONDS.convert(nanoSeconds, TimeUnit.NANOSECONDS);
How to Design a Good API & Why it Matters by Joshua Bloch
Joshua Bloch(effective java등의 저자)님의 api design에 대한 세미나 자료입니다.
http://www.infoq.com/presentations/effective-api-design
Java vs C# Serialize 비교와 C# DataSet을 쓰지 말아야 되는 이유(?)
며칠전에 사석에서 상사분이 톰캣(Tomcat)은 IIS에 비해서 connection을 적게 받고, 그로 인해서 성능이 떨어진다고 말씀을 하시네요. ^^;; 서비스의 전체적인 성능 문제를 자바(Java)나 톰캣이 문제가 있다는 시각이어서, 자바쪽의 경험치로 말씀하시는게 아니라 선입견(Overlapped I/O의 성능만 말씀하시네 ^^;;)으로 얘기를 하고 있다는 느낌이 많이 받았습니다. 대체로, 서비스의 성능 이슈는 톰캣이나 IIS보다 그 위에 올라가는 애플리케이션이 더 성능에 영향을 미칠텐데 말입니다. ^^;;
그래서 IIS 기반의 ASP.NET 서비스들이 주로 사용하는 DataSet에 대해서 Serialize 데이타에 대해서 살펴보았다. 비교는 단순히 자바, C# Object, C# DataSet으로 10개의 리스트를 가지는 모델을 가지고 했다. 아래의 코드로 자바에서의 Object Array, C#에서의 Object Array, C#에서의 DataSet의 Serialize된 객체의 사이즈를 알 수 있다. 단순하게 Serialize하는 속도 및 Deserialize하는 속도는 같다고 가정을 한다.
* Java
– SerializeModel.java
import java.util.ArrayList; import java.io.Serializable; public class SerializeModel implements Serializable { private static final long serialVersionUID = -7168303693593724718L; private int count = 0; private String name = null; private String address = null; private ArrayList<SerializeModel> models = new ArrayList<SerializeModel>(); public SerializeModel(int count, String name, String address) { this.count = count; this.name = name; this.address = address; } public void addModel(SerializeModel model) { this.models.add(model); } }
– SerializeTest.java
import java.io.FileOutputStream; import java.io.ObjectOutputStream; public class SerializeTest { public static void main(String[] args) throws Exception { ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("java.ser")); SerializeModel model = new SerializeModel(0, "a", "b"); for(int i=0; i<10; i++) { model.addModel(new SerializeModel(i, i +" name", i +" address")); } out.writeObject(model); out.flush(); out.close(); } }
* C#
– SerializeModel.cs
using System; using System.IO; using System.Runtime.Serialization; using System.Collections; using System.Collections.Generic; namespace SerialzieTest { [Serializable()] class SerializeModel { private int count = 0; private String name = null; private String address = null; private ArrayList models = new ArrayList(); public SerializeModel(int count, String name, String address) { this.count = count; this.name = name; this.address = address; } public void AddModel(SerializeModel model) { this.models.Add(model); } } }
– SerializeModelDataSet.cs
using System; using System.Data; using System.Collections.Generic; using System.Text; namespace SerialzieTest { [Serializable] class SerializeModelDataSet { private DataSet dataSet = new DataSet(); public void AddDataTable(DataTable table) { this.dataSet.Tables.Add(table); } public DataSet GetDataSet() { return this.dataSet; } } }
– Program.cs
using System; using System.Data; using System.IO; using System.Runtime.Serialization; using System.Runtime.Serialization.Formatters.Binary; namespace SerialzieTest { class Program { static void SerializeObjectArray() { Stream stream = File.Open("csharp.ser", FileMode.Create); BinaryFormatter bformat = new BinaryFormatter(); SerializeModel model = new SerializeModel(0, "a", "b"); for (int i = 0; i < 10; i++) { model.AddModel(new SerializeModel(i, i + " name", i + " address")); } bformat.Serialize(stream, model); stream.Flush(); stream.Close(); } static void SerializeDataSet() { Stream stream = File.Open("csharp_dataset.ser", FileMode.Create); BinaryFormatter bformat = new BinaryFormatter(); SerializeModelDataSet model = new SerializeModelDataSet(); DataTable table = new DataTable(); DataColumn itemCount = new DataColumn("count", Type.GetType("System.Int32")); DataColumn itemName = new DataColumn("name", Type.GetType("System.String")); DataColumn itemAddress = new DataColumn("address", Type.GetType("System.String")); table.Columns.Add(itemCount);</span> table.Columns.Add(itemName); table.Columns.Add(itemAddress); DataRow row; for (int i = 0; i < 10; i++) { row = table.NewRow(); row["count"] = i; row["name"] = i + " name"; row["address"] = i + " address"; table.Rows.Add(row); } model.AddDataTable(table); bformat.Serialize(stream, model); stream.Flush(); stream.Close(); } static void Main(string[] args) { SerializeObjectArray(); SerializeDataSet(); } } }
위 코드를 사용해서 저장한 Object의 사이즈는 아래와 같습니다.
C#(Object ArrayList) : 1035 byte
C#(DataSet) : 3000 byte
네트웍으로 전송되는 데이터의 크기는 성능에 중요한 영향을 준다는 것은 이미 알고 있다. 성능을 높이기 위해서 Socket Buffer의 사이즈를 적당히 줄이는 것도 팁중의 하나이다. 그리고, 위 코드로 만들어지는 C#의 DataSet은 더욱 멋진 모습을 보여준다. 아래의 화면처럼 말이죠.. 아래의 화면은 Hex Viewer로 본 화면이다.
Object의 Serialize는 C#이 version, locale 및 가비지(?) 데이타로 인해서 좀 더 크게 나온다. 그리고, 중간의 DataSet은 Serialize된 내용을 보면, xml의 형태로 데이터를 저장하고 있다. 결국 DataSet을 데이타로 직렬화해서 네트웍으로 전송하게 되면, 데이터 크기보다는 Serialize/Deserialize할때의 String연산(XML 데이타 리드)이 성능저하의 주범이 될 것 같다. 결국, Tomcat, IIS가 중요한게 아니라 C#에서 널리 쓰이는 DataSet을 많이 사용하고 있는 IIS기반의 ASP.NET 어플들의 서비스가 더 문제가 아닐까 생각한다.