태그 보관물: object

관계를 좀 더 쉽게 풀어내는 방법 : Activity Stream ????

눈 앞으로 다가온 물리적 웹의 시대에서 Physical Web, Object, Activity 등의 새로운 개념을 읽고, 포스팅 하신분께 요청해서 정보도 받고 해서, 좀 더 자세히 Activity Stream이라는 것에 대해서 살펴 보았습니다.. 포스팅 하신분께 감사드립니다..

포스팅 하신 분의 도움을 받아서, 제가 파악한 내용은, http://activitystrea.ms/ 이 Object의 Activity에 대한 정의, 그 정의를 바탕으로 한 관계에 대한 포맷에 대한 표준(?)을 제시하고 있더군요.. ^^.

결국, 데이타를 synd하는 포맷을 정의하고, 포맷된 데이타를 통해서 Object간의 관계를 알 수 있을 거 같습니다. 물론, 위치 정보 까지도요… 지금 하는 프로젝트(소셜 합니다..ㅋㅋ)에 써먹기에 참 좋은데 말이죠…

여튼, 기존의 관계가 들어있지 않았던 많은 데이타들이, 관계, 위치등을 기반으로하는 포맷으로 변환이 되서 유저들간의 관계를 좀 더 쉽게 풀어 내기를 기대해 봅니다..

Object.hashCode() vs System.identityHashCode(Object x)

보통 객체에 대한 고유값으로 hashCode() 메쏘드를 많이 사용한다. 최 상위 타입인 Object의 hashCode()는 Override가 가능하기 때문에, 고유값이 아닐경우가 잠재적으로 존재하게 된다. 이런 문제(?)를 해결할 수 있도록 System.identityHashCode(Object x)라는 메서드를 제공하고 있다.

그래서, 기존의 아래와 같은 방식을..

System.out.println(aa.hashCode());

아래의 코드로 바꿔야 한다.

System.out.println(System.identityHashCode(aa));

참고로, 아래처럼 Object가 null인 경우는 0이다.

System.out.println(System.identityHashCode(null));

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 &lt; 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 &lt; 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의 사이즈는 아래와 같습니다.

Java(Object ArrayList) : 665 byte
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 어플들의 서비스가 더 문제가 아닐까 생각한다.

Object의 Reference에 대한 내용..

자바 플랫폼의 경우 객체에 대해 네 가지 타입의 레퍼런스가 존재하는데, 일반적으로 사용하는 타입으로 Direct Reference를 들 수 있다.

   Object obj = new Object()
특히 Direct Reference는 객체 액세스를 위해 별도의 코딩을 필요로 하지 않는 일반 참조(strong references )라 할 수 있으며, 나머지 세 타입의 레퍼런스는 java.lang.ref 패키지에 포함되어 있는 Reference 클래스의 서브클래스들이다. Soft Reference는 SoftReference 클래스에 의해, Weak Reference는 WeakReference 클래스에 의해, 그리고 Phantom Reference는 PhantomReference 클래스에 의해 제공된다.

Soft Reference는 데이터 캐시와 그 기능이 유사한데, 시스템 메모리가 낮을 때 가비지 컬렉터는 Soft Reference가 유일한 레퍼런스인 객체를 임의로 비울 수 있다. 다시 말해서, 객체에 대한 일반 참조가 없는 경우 그 객체가 릴리즈 후보가 되는 것이다. 한편, 가비지 컬렉터는 OutOfMemoryException을 throw하기 전에 임의의 Soft Reference를 릴리즈해야 한다.

Weak Reference는 Soft Reference보다는 다소 불완전하다. 객체에 대한 유일한 레퍼런스가 Weak Rererence뿐이라면 가비지 컬렉터는 언제라도 오브젝트가 사용하는 메모리를 이용할 수 있으며, 메모리가 낮은 상태라면 별다른 요구사항은 발생하지 않는다. 일반적으로 객체가 사용하는 메모리는 후속 가비지 컬렉터 패스에서 이용된다.

Phantom Reference는 cleanup 작업과 관련이 있다. 이들은 가비지 컬렉터가 마무리 과정을 수행하고 객체를 비우기 바로 직전에 통지를 하는데, 이는 객체 내에서 cleanup 작업을 수행하는 방법 중 한 가지라고 생각하면 된다.

객체생성 방법

1. new keyword
– 일반적으로 많이 쓰이는 방법

MyObject
object = new MyObject();

2. Class.forName()
– reflection을 이용해서 생성자 호출해서 생성

MyObject object = (MyObject)
Class.forName(“net.sjava.socket.Acceptor”).newInstance();

3. clone()
– clone() 를 통해 기존 오브젝트의 복제본을 사용, shallow copy본이기 때문에 주의 필요

MyObject mObject = new MyObject();
MyObject object = mObject.clone();

4. object deserialization
ObjectInputStream
inStream = new ObjectInputStream(testInputStream);