참조 사이트 - http://hgh73.blog.me/90071375211


안녕하세요 저는 길당 이라 합니다...

자카르타 톰캣의 설치에 이어 환경설정에  관한 글을 올립니다...

=================================================================================

 

 

[환경 설정]

 

[아파치 웹 서버와 톰캣 연결]

 

일반적으로 J2EE 컨테이너는 독립적으로 사용되기보다는 웹 서버와 연동해서 사용되는 경우가 더 많다. 물론 톰캣 자체에도 웹 서버 기능이 내장되어 있지만 톰캣만으로 서비스를 구성하지 않고 아파치 웹 서버 혹은 IIS와 같은 외부 웹 서버를 이용하는 것이 바람직하다.

 

그 이유로는 톰캣에 포함되어 있는 웹 서버 기능은 다른 상용 혹은 웹 서버에 비해서 성능 상으로 많이 떨어진다. 구축하고자 하는 시스템이 서블릿/JSP 뿐만 아니라 펄, PHP, ASP 등 다양한 기술을 이용해서 서비스를 이용해야 하는 경우 톰캣만으로는 불가능하기 때문이다.

 

그 외에 하나의 서버에 웹 서버와 웹 컨테이너를 모두 설치하여 사용하는 경우 시스템에 많은 부하를 주게 되며 하나의 시스템 장애로 인해 모든 서비스가 정지되는 문제가 있어 각각 다른 서버에서 서비스를 하는 것이 여러모로 유리하다.

이렇게 웹 서버와 웹 컨테이너를 분리하기 위해서는 웹 서버를 시작점으로 해서 웹 컨테이너로 요청을 보내도록 시스템 구성을 하여야 한다. 어쨌든 이 책에서는 하나의 시스템에 웹 서버와 웹 컨테이너를 모두 설치해서 진행하지만 분리 방안에 대해서도 한번 생각해 보는 것이 바람직하다.

 

톰캣과 아파치 웹 서버와 연결하는 방법은 크게 두 가지가 있다.

 

첫 번째로 가장 범용적으로 쓸 수 있는 커넥터가 APJ이다. 현재 1.3 버전까지 나와 있는데 이 버전의 장점은 톰캣의 버전과 아파치 웹 서버의 버전에 관계없이 사용할 수 있다는 점이다. 특히 톰캣 3.x 대 버전을 사용하거나 아파치 웹 서버 2.x 대 버전을 사용한다면 현재는 APJ가 유일한 연결 방법이며 IIS와도 연결이 가능하다.

 

두 번째 방법은 WARP 커넥터를 이용하는 것으로 WARP는 APJ에 비해서 설정하기 편리하며 좀더 좋은 성능을 발휘한다. 이러한 이유로 일반적으로 톰캣 4.0 버전에서는 WARP를 이용한 연결을 사용하며 이 책에서는 WARP 방식을 이용한 연결을 소개하도록 하겠다.

WARP를 이용해서 아파치 웹 서버와 톰캣을 연결하는 작업은 다음 절차를 따른다.

 

① WARP 모듈을 다운로드
② 아파치 웹 서버에 WARP 모듈 인식시키는 작업
③ 아파치 웹 서버에 톰캣의 정보 설정
④ 서비스하고자 하는 톰캣의 웹 어플리케이션 지정

그럼 위의 4가지 절차에 따라 하나 하나 알아보도록 하자.

 

이 글을 쓰는 현재에 
http://jakarta.apache.org/builds/jakarta-tomcat-4.0/release/v4.0.3/bin/linux/i386/에서 mod_webapp.so에서 WARP 커넥터를 다운로드 받을 수 있다.


이 파일의 위치는 톰캣 버전이 변경되거나 WARP 버전이 업그레이드 될 때마다 다운로드 받은 위치가 변경되곤 한다.

 

다운로드한 mod_webapp.so를 $(APACHE_HOME)/libexec로 복사하자.

 Libexec 디렉토리는 아파치 웹 서버에 추가 모듈을 설치할 때 해당 모듈을 저장하는 곳이다. 특히 아파치 웹 서버를 소스 코드 상태에서 컴파일해서 설치하였을 경우 반드시 DSO를 설정해서 설치해야 한다.


그래야만 추가 모듈을 인식시킬 수 있다. 저장을 했으면 아파치 웹 서버에 해당 모듈을 인식시키는 작업을 해야 한다. $(APACHE_HOME)/conf/httpd.conf 파일에 다음 내용을 추가하도록 하자.

 


 

 

 

LoadModule webapp_module libexec/mod_webapp.so

 

AddModule mod_webapp.c

 

이상으로 톰캣의 설치와 실행 및 종료 방법에 대해서 알아보았다. 다음은 아파치 웹 서버와 톰캣을 연결해서 서비스를 제공하는 방법에 대해서 알아보도록 하겠다.

 

위의 두 가지 내용은 httpd.conf의 적당한 위치에 각각 추가하도록 하자. 한가지 주의할 점은 반드시 LoadModule이 AddModule 보다 먼저 나와야 한다.

 

그럼 정상적으로 httpd.conf 파일이 작성되었는지 테스트하기 위해 다음 명령을 수행하자.

 

$(APACHE_HOME)/bin/apachectl configtest

 

위의 명령을 수행하면 httpd.conf의 문법에 이상이 없는지를 확인한다. 이상이 없으면 'Syntax OK' 메시지가, 이상이 있으면 문제가 있는 줄의 번호와 간단한 이유를 보여준다.

 

 

[그림 6]과 같은 결과를 얻었다면 일단 환경 설정 상으로는 문제가 없는 것이며 해당 모듈을 아파치 웹 서버가 인식할 수 있다는 것을 의미한다. 그 다음으로 할 일은 아파치 웹 서버에게 톰캣과 관련된 정보를 인식시켜 주는 것이다.


가장 일반적인 예로 톰캣에서 샘플로 제공되는 웹 애플리케이션과 아파치 웹 서버를 연결하는 것으로 다음 내용을 $(APACHE_HOME)/conf/httpd.conf에 추가하자.

 

 

<IfModule mod_webapp.c>

WebAppConnection conn warp localhost:8008

WebAppDeploy ROOT conn /

WebAppDeploy examples conn /examples

WebAppinfo /webapp-info

</IfModule>

 

위의 내용이 전형적으로 WARP를 이용한 연결 예이다. 대부분의 아파치 웹 서버와 톰캣 연결에 대한 설명에서 이 예를 사용하는데 각각의 내용에 대해서 하나 하나 짚고 넘어가보자.


우선 해야 할 것은 자카르타 톰캣이 위치한 서버의 IP 주소 혹은 도메인 네임과 서비스되고 있는 포트를 지정하는 것이다. 이 역할이 WebAppConnection이다. 먼저 첫 번째 줄에 위치한 다음 내용을 분석해 보자.

 

 

여기서 conn은 톰캣에 연결할 연결 명을 의미하며 warp는 WARP 방식으로 하겠다는 의미이다. 여기에서 현재 사용 가능한 연결 방식은 WARP 밖에 존재하지 않으므로 반드시 warp라고 기록해 주어야 한다.


그 다음에 톰캣의 주소를 입력하면 된다. 아파치 웹 서버와 톰캣이 동일한 서버에 위치해 있다면 localhost로 입력하고, 다른 서버에 위치한다면 해당 서버의 위치를 지정해 주면 된다. 그 다음에 나오는 8008은 WARP 서비스 포트이다.

 

일반적으로 톰캣의 서비스 포트는 8080을 이용한다. 그러한 이유로 이곳에 8080을 기입하는 경우가 종종 있는데 그것은 잘못된 설정이다. 톰캣의 서비스 포트와 WARP의 접속 포트는 항상 별개로 동작한다.

 

그러므로 반드시 WARP 서비스 포트를 기입해야 하며 기본값이 8008이다. 이 포트 번호를 수정하고자 한다면 $(CATALINA_HOME)/conf/server.xml에 다음과 같은 환경 설정 내용이 있는데 여기서 port 값은 변경해 주면 된다.

 


톰캣 뿐만 아니라 J2EE에 규정된 모든 서블릿 컨테이너들은 웹 환경의 서비스를 제공하기 위해서는 최소한 하나의 웹 애플리케이션이 존재해야 한다.

 

여기서 말하는 웹 애플리케이션이란 웹 서비스를 제공하기 위한 자원들 즉 서블릿, JSP, 자바 빈즈, 이미지, HTML 들을 모아 놓은 그룹이다. 서블릿 컨테이너들은 여러 개의 웹 애플리케이션이 모여서 하나의 도메인을 구성한다. 톰캣의 경우는 기본적으로 ROOT, sample, manager 웹 애플리케이션을 제공하고 있다.

 

ROOT는 가장 기본이 되는 웹 애플리케이션으로 아파치 웹 서버에서 DocumentRoot에 해당하는 부분이다.

 

Sample은 톰캣을 설치하고 간단히 테스트해 볼 수 있는 서블릿과 JSP 예제들을 모아 놓은 부분이며 manager는 톰캣에 웹 애플리케이션을 정의하고 제거하며 기타 여러 가지 관리 기능을 제공하지만 그 기능이 아주 미약하고 사용하기 불편해서 거의 사용하지는 않는다.

 

위의 예에서 WebAppDeploy 항목이 톰캣에 존재하는 웹 애플리케이션을 아파치 웹 서버에게 알리는 역할을 한다. 만일 톰캣에 웹 애플리케이션이 존재하더라도 WebAppDeploy에 기입하지 않았을 경우에는 아파치 웹 서버에서는 이 내용에 대해서 인식하지 못한다. 다음 내용을 분석해 보자.

 

 

처음 WebAppDeploy는 웹 애플리케이션을 배포하겠다는 의미이며 examples는 해당 웹 애플리케이션의 이름이다.

 

이 이름은 톰캣에 정의되어 있어야만 한다. 그 다음을 해당 웹 애플리케이션이 어떠한 WARP 연결을 통해 서비스를 제공하겠냐는 의미이다. 앞서 우리는 conn이 하는 WARP 커넥터를 정의하였다.

 

그 다음에 나오는 것이 중요한데 /examples가 나타내는 의미는 해당 웹 애플리케이션에 웹 브라우저를 이용해 접속할 때에 필요한 URL 이름이 된다. 이렇게 정의된 웹 애플리케이션은 웹 브라우저에서 다음과 같은 형태로 접근하게 된다.

 

http://<domain-name>/examples

 

이 내용들을 자신의 환경에 맞게 적절히 적용시킨 후에 다시 아파치 웹 서버의 환경 설정을 검증해 보자. [그림 7]과 같은 결과가 나오면 성공적으로 환경 설정이 이루어졌음을 의미한다.

 

 

 

 

환경 설정이 완료되었으니 다음 두 개의 URL로 접속해 보자.

 

http://<domain-name>/examples/j네/index.html


http://<domain-name>:8080/examples/j네/index.html

 

첫 번째 URL은 아파치 웹 서버를 통해 톰캣에 접속한 것이고 두 번째 URL은 톰캣에 직접 접속한 것이다. 위의 내용이 동일하게 보인다면 WARP 설정은 완성된 것이다.

 

 

 

 

[JDBC 환경 설정]

 

JDBC란 뒤에 자세히 설명하겠지만 자바에서 데이터베이스 처리를 하기 위한 기술이다.

 

JDBC 연결을 하는 것은 상당히 쉬우며 DBMS에 맞는 JDBC 드라이버를 다운로드 받아서 클래스패스에 해당 드라이버를 추가해 주는 것으로 끝난다. 현재 나오는 대부분의 DBMS들은 JDBC를 지원하고 있다. 하지만 애석하게도 MySQL은 공식적으로 JDBC를 지원하지 않고 있으며 그러한 이유로 공식적인 JDBC 드라이버도 없다. 

다만 여러 서드 파티에서 드라이버를 제공한다. 다음 제품들이 MySQL에서 JDBC를 사용할 수 있는 드라이버이다.

·

mm JDBC 1.2 드라이버 · mm JDBC 2.0 드라이버
· 상업용 Resin JDBC 드라이버 · TWZ 드라이버

 

이 중에서 가장 많이 사용되는 드라이버는 mm 드라이버로 1.2 버전은 
http://www.mysql.com/Downloads/Contrib/mm.mysql.jdbc-1.2c.tar.gz 에서 받을 수 있으며 2.0 버전은 http://www.mysql.com/Downloads/Contrib/mm.mysql-2.0.4-bin.jar 에서 받을 수 있다.

[나는 현재 여기에서 받았다. http://mmmysql.sourceforge.net/oldDist.html ]

 

 

이 책에서는 mm JDBC 2.0 드라이버를 이용하도록 하겠다. 이 드라이버가 현재 JDBC 2.0을 지원한다고는 하나 아직 완벽한 지원을 하는 것은 아니고 일부 기능만을 제공한다.

 

드라이버를 다운로드 받았다면 이제 JDK와 톰캣에 인식을 시켜야 한다. 한 가지 주의할 점은 JDK의 클래스패스와 톰캣의 클래스패스는 동일하지 않다는 점이다. 그러므로 두 곳 모두 인식을 시켜야 하는데 톰캣의 경우 간단하게 다음 디렉토리에 저장하면 자동으로 인식한다.

 

$(CATALINA_HOME)/common/lib

 

위의 디렉토리는 MySQL 드라이버뿐만 아니라 톰캣과 관련된 다양한 자바 라이브러리를 저장하는 곳으로 활용하면 좋다.
이제 JDK에 인식을 시켜야 하는데 JDK는 다음과 같이 CLASSPATH를 수정함으로써 해결하도록 하자.

 

CLASSPATH=.:$CATALINA_HOME/common/lib/servlet.jar:$CATALINA_HOME/common/lib/mm.mysql-2.0.4-bin.jar

 

 

설정이 완료되었으면 MySQL에 접속하는 자바 애플리케이션을 만들어 보자. JSP에서도 마찬가지로 JDBC로 MySQL에 접근하므로 다음 예제와 겅의 동일한 형태로 이루어진다.

[<리스트1> DriverManageExample.java]

 

 

 

<리스트 1>은 단지 데이터베이스에 연결 가능 여부를 판단하는 예이다.

 

특별히 SQL을 이용한 데이터베이스 처리 내용은 담겨 있지 않지만 JDBC를 처음 접하는 개발자들의 대부분이 데이터베이스에 연결하는 방버으로 고민하고 있는 것을 보면 위의 예제는 나름대로 큰 의미가 있다고 할 수 있다.


<리스트 1>을 수행하면 Access denied 에러가 날것이다. JDBC를 연결할 때에는 사용자와 비밀번호를 입력해야 하기 때문이다. <리스트 1>의 내용 중 user 부분과 password 부분을 Mysql의 mysql 데이터베이스의 user 테이블에 등록된 사용자로 변경해 주자.

 

Connection con = DriverManager.getConnection(dbURL, "user", "password");

 

만일 MySQL이 다른 리눅스 서버에 설치되어 있다면 해당 서버의 도메인 네임 혹은 IP를 이용해야 하며 다음 내용을 적절히 수정해서 사용하기 바란다.

 

String dbURL = "jdbc:mysql://localhost:3306/test";

 

위의 문자열을 흔히 JDBC URL이라고 한다. 여기서 'jdbc:mysql://'은 MySQL에 JDBC를 사용하기 위해 필요한 것이며 그 이후에 MySQL의 위치와 포트 번호 그리고 최종적으로 접근하고자 하는 DB의 이름이다.

 

자바에서 데이터베이스를 활용하기 위해서는 java.sql 패키지를 이용해야 한다. 이 외에도 J2EE API에는 javax.sql 패키지도 있지만 이 책에서는 이용하지 않겠다.

 

Java.sql 패키지에는 DB와 관련된 많은 클래스와 인터페이스가 있지만 그 중에서 데이터베이스 연결과 관련된 것은 Driver, DriverManager, Connection 클래스이다. 이 중에서 Driver의 경우 잘 사용되지 않으며 대부분 DriverManager와 Connection을 이용해 연결을 수행한다.

 

DriverManager는 메모리에 로드된 드라이버를 관리해 주는 역할을 한다. 특히 중요한 역할은 해당 애플리케이션이 여러 종류의 데이터베이스를 처리해야 하거나 다양한 종류의 드라이버를 사용할 필요가 있을 경우에 DriverManager를 이용한 처리가 반드시 필요하다.

 

여러 종류의 드라이버가 DriverManager에 등록되면 DriverManager에게 원하는 데이터베이스 연결을 요청하게 된다. 이 때 DriverManager에서는 요청한 JDBC URL을 분석해서 적절한 드라이버를 이용해 Connection 객체를 리턴한다.

 

그 이후에 데이터베이스 처리와 관련된 모든것들은 Connection 객체를 통해서 이루어지며 Connection 객체가 종료가 되면 다른 모든 처리 역시 종료된다. 이 때 한 가지 주의할 것이 있다.

 

자바는 C++과는 다르게 객체의 해제를 가비기 컬렉션을 이용해서 자동으로 제거해 주는데 예외적으로 몇몇 객체들은 가비지 컬렉션 대상에서 제외된다. 대표적인 것이 데이터베이스 연결 객체인 Connection과 소켓 객체인 Socket 등이 있다.

 

이 객체들은 close 메소드를 호출해서 종료하지 않는 한 계속해서 시스템에 남아 있게 되며 그 만큼 시스템에 많은 부담을 주게 되는 것이다. 그럼 이제 JSP를 사용하기 위한 환경 설정이 완료되었다. 본격적으로 JSP에 대해서 알아보도록 하자.

 

[tip] mysql 설정하기

 

 

 

 

 

Posted by linuxism

댓글을 달아 주세요

1. 사용권한

- Root 사용자 권한에서만 사용하려면 ...
 * /root 디렉토리에서 .bash_profile을 수정

- 특정 계정에서만 JDK 를 사용하도록 하려면...
 * 각 계정의 홈디렉토리 내의 .bash_profile 파일 수정

- 모든사용자 사용할 수 있도록 설정

 * /etc/profile 파일 수정


2. 설정

/etc/profile 에 다음을 추가


#java CLASSPATH

CLASSPATH=.:/usr/local/"자신의tomcat디렉토리 이름"/common/lib/servlet-api.jar
export CLASSPATH


3. 변경된 설정을 시스템에 적용
# source /etc/profile


4. CLASSPATH 란?

CLASSPATH 를 알기 위해서 우선 class 와 path 에 대해서 짚고 넘어 가도록 하겠습니다.

* CLASS

자바로 코딩을 할때 보통 AboutJsp.java 와 같이 만들게 됩니다. 그리고 그걸 javac 를 이용해서 컴파일을 하면 자바 바이너리 파일 즉, class 파일이 생성됩니다. 이러한 class 파일은 직접 실행( # java AboutJsp 와 같이 커맨드 라인에서 직접) 할수도 있고, 다른 프로그램에서 그 class 파일을 가져다가(상속이나 특정 목적에 의해서 import 하여.. ) 사용할수도 있습니다. 어째든 뭐뭐.java 파일을 컴파일한 것이 class 파일입니다.


* PATH

PATH 는 경로(위치)를 뜻합니다. 예전 도스를 사용해 보신 분들이 무엇인지 아시겟지요? 유닉스(리눅스)에서도 현재까지 쓰이고 있는데요, path 라는 환경변수를 하나 설정하고 이곳에 디렉토리를 나열해(쉘 마다 나열방식은 약간 다름) 놓은후, 특정 명령어를 프롬프트에 입력하게되면 그 명령어를 path 에 나열된 디렉토리에서 찾아서 실행하게됩니다. (나열된 가장 앞 디렉토리 부터 검색) 따라서 특정 명령어를 실행시키 위해서 그 파일이 있는 디렉토리 까지 움직일 필요는 없게 됩니다.


결국 CLASSPATH 라는 것은 CLASS 파일이 저장되어 있는 디렉토리의 나열을 말하는 것이죠. 자바 프로그램에서 어떤 CLASS 파일을 요청했을때 컴파일러는 CLASSPATH 에 지정되어 있는 디렉토리에서 해당 CLASS 파일을 찾으려 하게되는 것입니다.. 
아뭏튼 CLASSPATH 는 CLASS 파일이 저장된 디렉토리의 나열 이라는것! 이것만 기억해 두시고 넘어 가도록 합시다


* CLASSPATH 설정하기

CLASSPATH 는 일반 PATH 와는 달리 디렉토리 외에 파일을 지정할수도 있는데, 지정할수 있는 파일의 종류는 *.jar, *.zip 등이 있습니다. jar 파일은 class 파일을 묶어서 압축해 놓은 파일로, 이 파일을 CLASSPATH 에 추가 하게 되면 그 파일안에 class 파일을 모두 사용할수 있게 됩니다. 정리해서 말하자면 classpath 에는 class 들이 저장되어 있는 디렉토리와, 그러한 class 파일을 묶어 놓은 jar 혹은 zip 파일등을 지정할수 있는 것입니다. 한가지 주의 할점은 classpath 에 지정된 디렉토리에 jar 파일을 놓아 둔다고 해서 사용가능해지지는 않는 다는 것입니다. jar 파일은 반드시 classpath 의 한 구성요소 이어야만 합니다.

 

-classpath 옵션은 해당 프로그램에서 사용할 라이브러리를 선택적으로 이용할수 있도록 하기 위한 옵션 입니다.

프로그램을 만들기 위해서는 상황에 따라 기능에 따라 여러 라이브러리를 포함 할수가 있는데 만약 선택적인 옵션이 없다면 모든 라이브러리를 프로그램에서 포함을 시켜야 합니다. 이러한 경우 불필요한 라이브러리 까지 포함하기 때문에 비 효율적이 겠지요..

이러한 문제는 비단 자바 뿐만 아니라 모든 언어가 같습니다.

단지 어떻게 라이브러리를 참조 하느냐가 다를뿐..

 

-classpath옵션을 사용하는 방법은 여러가지가 있습니다.

도스콘솔에서 해당 클래스를 컴파일 할때 -classpath옵션을 주어 적용 할수 있고 환경변수에 추가 시켜 사용할수 있습니다.

 

이클립스에서 라이브러리를 참조 하는 방법은 여러가지 방법이 있습니다.

 

첫번째 방법은 프로젝트를 생성할때 Java Settings 단계에서 포함 시킬 수 있는데 라이브러리 탭에서 Add External JARs 버튼을 눌러 포함 하고자 하는 jar파일을 선택 하시면 됩니다.

자주 사용하는 jar파일 이라면 Add Variable 버튼을 눌러 변수로 만들어 사용할수도 있습니다.

 

두번째 방법은 이미 프로젝트가 생성되어 있는 경우 포함 하는 방법인데 해당 프로젝트를 열어 두고 Project > Properties > Java Build Path > Libraries탭에서 첫번째 방법과 같이 라이브러리를 포함 할수 있습니다.

[출처] * CLASSPATH 란? |작성자 sujikang2000

Posted by linuxism

댓글을 달아 주세요

JVM 메모리

Development/Java 2010. 11. 15. 16:54
JVM은 실행될 클래스파일을 메모리에 로드후 초기화작업을 수행한다. 초기화하면서 메소드와 클래스변수 들을 해당 메모리영역에 배치한다. 클래스로드가 끝난후 JVM은 main메소드를 찾아 지역변수 , 객체변수 , 참조변수를 스택에 쌓고 다음 라인을 읽으면서 함수를 호출할것인지 힙에 객체를할당할것인지등.. 여러 작업을 하게됩니다.


JVM 메모리구조

1. 메소드영역 : 메소드의 바이트코드 , 클래스변수가 저장되는 영역

2. 힙 영역 : 프로그램 실행중 생성된 객체가 저장되는 영역

3. 스텍 영역 : 메소드 내의 지역변수 , 매개변수(참조형 제외)가 저장되는 영역

4. pc 레지스터 : jvm이 현제 수행할 명령어의 주소가 저장되는 영역

5. Native메소드 스텍 : JAVA어 외의 다른 언어의 메소드에 매개변수 , 지역변수가 저장되는 영역


메소드영역에 관한 짧막한 설명..
객체를 여러번찍으면 객체 속성변수는 그렇다치고 메소드들은 메소드영역에 찍히게됩니다.
여러 객체를 찍을때마다 메소드가 중복되어 메소드영역에 저장되는게 아니라 하나의 메소드를 가지고
해당클래스의 객체가 그 메소드를 공유하여 사용한다는것입니다. 사용할때는 메소드를 호출할때 객체의 정보를 일부 포함시켜 넘겨주어 어떤 객체의 메소드를 처리할것인가를 구별합니다. 이는 프로그래머가 하는게아니라 JVM내부적으로 일어나는 일이기때문에
크게 신경쓰지 않아도 되는일입니다. 다른 예를 들자면 메소드영역에는 클래스변수가 저장되는데 이또한 객체가 공유하는 변수가 되겠습니다.

======================================================================================




출처 -  http://www.cyworld.com/crazyprogram/4896771 
========================================================================================

● 자바 메모리(JVM) 구조

1. 상속관계를 이용하여 메모리 구조를 이해해 보자.

부모(Parent, Base, Super)와 자식(Child, Derived, Sub)은 계층 구조를 이룬다.

 

1) 메모리 특징

  • 힙영역: 자식을 생성하면 반드시 부모도 생성된다(아래 그림에서 자식 A가 메모리에 올라갈때 A와 Parent가 같이 올라간다).
  • 스태틱영역(Method Area) : 자식의 설계도가 올라가면 부모의 설계도도 같이 올라간다. 

    - 모든 메서드(클래스 메서드, 인스턴스 메서드)는 스태틱영역에 로드된다. 하지만 여기서 클래스 메서드인 경우는 인스턴스 생성없이 클래스 이름으로 바로 호출 가능하고 인스턴스 메서드는 객체를 생성해야 한다. 인스턴스 메서드는 인스턴스 변수를 사용하기 때문이다.!!!!

    - 생성된 객체의 참조 주소는 부모의 주소다.

         

A a2=new A();

에서 a2를 살펴보자. 설계도영역에 올라간 A 타입은 Parent 타입의 자식이므로 A가 메모리에 설계도 영역에 올라가면 부모 Parent도 같이 올라간다. 그리고 힙영역에 A 객체가 생성되면 부모인 Parent의 객체도 생성되며 레퍼런스 a2는 부모 Parent의 주소를 참조한다.

[출처] 메모리 구조 기본 (1)-섹션 143|작성자 자바자바

 

http://blog.naver.com/honnynoop/22805940 -

 

 

 2. 객체 생성시에 메모리 구조를 이해해보자 

 

 

 인스턴스 생성시 각 인스턴스 멤버는 새로운 메모리(Heap 영역)에 할당 되지만 인스턴스 메소드는 Method 영역에 있는 하나를 공유한다. 메소드는 한 개만 존재하는데 메소드가 호출되면 제어가 메소드로 정의로 넘어 가는데 어떻게 인스턴스 멤버를 구분해서 해당 인스턴스 멤버의 내용을 출력할까?

이 의문에 대한 열쇠가 바로 래퍼런스 this이다.

자바의 모든 인스턴스 메서드(생성자 포함)는 this(레퍼런스 변수)를 기본적으로 가지고 있다가 해당 메서드을 호출한 매서드의 this(레퍼런스 변수)의 값을 넘겨받는다. 메서드에서 사용되는 모든 필드는 사실은 this로 접근하는 것이다.

------------------------------

인스턴스 메서드(생성자 포함)는 자신을 호출한 메서드의 this값을 넘겨 받는다.

여기서 문제가 두개 보였다.

1. 하나의 (1)메서드가 다른 (2)메서드에게 this값을 넘겨 준다고 생각하면 (2)다른메서드가 (3)또다른메서드를 호출하게 되면 자신의 this값을 어떻게 넘겨 주냐 하는 문제가 발생한다. 두번째 메서드에는 이미 첫번째 메서드의this 값을 갖고 있는데….

2. this가 자신의 인스턴스를 가리킨다. 즉 멤버필드와 메서드필드가 다른 영역에 저장되는데 this로 어떻게 이 둘을 다 가리킬 수 있는지를…. .. 생각해보는것이..  

 

 

예제를 메모리화 해보자!!

public class Main {

public static void main(String[] args) {

Operation test = new Operation();

Point A1=new Point(100,100);

static int mul=0;

test.setX(10);

test.setY(20);

System.out.println(text.add());

System.out.println(Operation.multi(10, 20));

}

}

public class Point {

private int x;

private int y;

public Point() { this(0, 0); }

public Point(int x, int y) {

setX(x);

setY(y);

}

public int getX() { return x; }

final void setX(int x) { this.x = x; }

public int getY() { return y; }

final void setY(int y) { this.y = y; }

}

public class Operation extends Point{

int sum=0;

public Operation(){ super(0,0); }

public int add(){

sum = super.getX()+super.getY();

return sum;

}

static int multi(int a, int b){

mul = a *b;

return mul;

 

}

 

개념적으로...

 

 

메모리 구조

 

1. new 연산자를 통해 Heap 인스턴스가 생성되었다. 그리고 클래스 변수인 mul 초기화 되었다.

 

 

 

2. test.setX(10)와 test.setY(20)으로 Heap Area 있는 인스턴스 멤버를 초기화 한다. 각 멤버의 접근지정자가 private이기 때문에 다른 클래스에서 접근할 수 있도록 메서드를 만듬. getX()와 getY()메서드는 출력을 위해. (A1 인스턴스 제외)

 

 

3. add() 메서드는 인스턴스 메서드이기 때문에 참조변수로 접근 this.add();

X=10, y=20 초기화 했던 것을 더한다.

 

 

4. mutil()는 클래스 메서드이기 때문에 클래스명으로 접근. Operation.mutil();

 

 

출처 -  http://force44.blog.me/130095188664 
 
Posted by linuxism

댓글을 달아 주세요