우리가 객체를 복사할때 Clone() 을 사용합니다. 하지만 이경우, 객체가 가지고 있는 Sub 객체는 복사되지 않고, 주소 정보만 가지고 있게 됩니다.


hOriginalMap = new HashMap();

hOriginalMap.put("key1", "value1");

hOriSubMap = new HashMap();

hOriSubMap.put("subKey1","subValue1");

hOriginalMap.put("keyObj1", hOriSubMap);


HashMap hNewMap = null;

hNewMap = (HashMap)hOriginalMap.clone();



<<Shallow copy 결과>>

Original Map address=[3526198]

new      Map address=[7699183]

Original Sub Map address=[14285251]  <== 같은 주소값 

new      Sub Map address=[14285251]  <== 같은 주소값



위에서 hOriginalMap 과 hNewMap 객체는 서로 다른 주소값을 가지게 되지만,

hOriSubMap 객체의 경우에는 같은 주소값을 가지게 되는 것입니다.

이와 같은 복사 방식을 ShallowCopy 라고 합니다.


그러면 Sub 객체 까지 새로운 메모리 주소로 복사를 하기 위해서는

hOriginalMap 객체 또한 Clone 해서 hNewMap 에 담아 줘야만 Sub 객체를 포함해서

복사를 할 수 있는 것입니다.


하지만 Data Set이 계층형의 복잡한 구조라고 하면, 구조 정보를 파악해서 각각을 복사한다는 것은 쉬운일이 아닙니다. 또한 이러한 Data set이 여러개라면 각각의 Data Set 별로 객체를 복사해서 처리하기는 어렵습니다.


이럴경우, 아래와 같이 하면 객체를 복사 할 수 있습니다.


Object  => Object OutputStream=> new Object InputStream => new Object



아래는 복사하는 방법입니다.


hNewMap = null;

ByteArrayOutputStream byteArrOs;

ObjectOutputStream objOs;

ByteArrayInputStream byteArrIs;

ObjectInputStream objIs;

Object deepCopy;


HashMap hOriginalMap = new HashMap();

byteArrOs = new ByteArrayOutputStream();

objOs = new ObjectOutputStream(byteArrOs);

objOs.writeObject(hOriginalMap);

byteArrIs = new ByteArrayInputStream(byteArrOs.toByteArray());

objIs = new ObjectInputStream(byteArrIs);

deepCopy = objIs.readObject();

hNewMap = (HashMap)deepCopy;

 

 


Object stream을 이용하면 Remote 통신에서 json 등 Plain text 가 아닌 원격지에 동적 java Object를 생성하여 Model 객체를 자동생성 할 수도 있습니다.

 

복잡한 객체 Deep copy 하느라 고생하지 마세요~~^^;


 

 

 


'Java' 카테고리의 다른 글

IE11 관련 Javascript 수정사항  (0) 2017.03.06
java 소켓 연결 Timeout 설정  (0) 2017.02.01
Posted by 우진2015
,

일반적인 Web application에서는 단일 thread에 의해 공유자원이 사용 됨으로 잘 발생하지 않습니다. 그러나 Client가 동시에 여러개의 Request를 요청할 때 발생 할 가능성이 있습니다. 물론 서버의 성능이 좋다면 발생하는 가능성이 줄어들기는 하지만, 근본적으로 Application 개발시 Session사용의 부주의로 인해서 발생한다고 생각합니다.


Client에서 동시에 여러개의 Request를 서버로 보내면, 서버는 각각의 Thread가 Request에 대한 업무를 처리합니다.

이 Exception은 동시에 여러개의 Thread가 단일 Session 정보를 공유하고, 갱신하기에 발생하는 문제입니다.


JEUS의 경우 로그에서 “jeus.sessionmanager.util.SerializationException: failed to serialize a attribute” 를 볼 수 있는데, 이로 인해서 문제해결이 session의 자체의 문제로 생각 할 수 있었을 것으로 보입니다.


하지만,  Session의 정보를 여러 thread가 동시에 수정하다 보니 내용의 무결성이 회손되고, 그로 인해 이와 같이 exception이 발생한 것으로 보입니다.


따라서 다중 Thread가 단일 Session정보를 공유 할때는 공유자원에 대한 동기화 작업이 필요합니다.


또는 session에 저장하는 객체를 Thread safe 한 concurrentHashMap 을 사용하는 방법도 있습니다.


무엇보다 웹 어플리케이션에서는 어플리케이션을 개발 할때는 Thread safe 한지 반드시 고려해서 작업이 진행 되어야 합니다.


만약 Application 개발 구조 자체가 너무 많은 정보를 Session에 담아서 사용하고 있으며, 성능에 대한 이슈로 인해서  동기화도 불가하다면, Session에 있는 IO 정보를 별도 메모리에 카피하여 진행하고, 완료시 Session 값을 업데이트 하는 방식으로 Session 사용 부분을 최소화 하여 문제를 처리 할 수있습니다.


<<처리방법>>

1. Session에 저장 객체 동기화(Synchronized) ==> Thread safe

2. concurrentHashMap 사용 ==> Thread Safe

3. 내부 business layer까지 같은 객체 주소 사용 할 경우, 객체 복사 후 업무처리로 Session 의존성 최소화 ==> Thread safe + Deep copy


복잡한 구조의 객체를 사용 할 경우에는 Deep Copy를 활용하여 객체를 복사 할 수 있습니다.  


'TA' 카테고리의 다른 글

Performance Test  (0) 2020.09.10
Jquery CDN 설정관련  (0) 2017.01.31
Posted by 우진2015
,

EJB Deploy를 위해서 각각의 Bean component에서 참조하는 library가 독립된 memory 영역에 위치해야만 한다. 따라서 Application 설계시 이러한 Bean 모듈 캡슐화를 고려해야만하다.

Jeus의 경우에 유틸 및 공통 라이브러리 또는 다 도메인 참조등 각 Bean에서 참조할 수있는 Shared memory area를 지원하고 있다. 하지만, 이부분은 공유되는 자원이 매우 작을때 한정적으로 사용 가능 할 것이다. shared memory를 많이 사용하게되면, 각각의 Bean의 덩치가 커지게 되며, 이는 오히려 서비스의 효율을 떨어뜨리고, 자원사용에 문제점을 야기 할 수도 있다.

EJB를트랜젝션 관리로만 사용하고 있고, java reflection를 통해서 비즈니스 어플리케이션을 호출하고 있는 시스템에서 Hot deploy 기능을 구현 할 수 있지 않을까?

jeus command (hot-deploy)

- undeploy

undeploy -con container_name -mod module_type -n application_name

- deploy

deploy -n application_name

 

 

Posted by 우진2015
,