Socket Server 질문입니다. (왕초보입니다.)

sjjloveangel의 이미지

안녕하세요! 고수님들 자바를 공부하고 있는 초보입니다.

Socket을 써서 client에서 server로 접속을 했을 때 server에서 Data를 client로 주는 Socket program을 아래와 같이 만들었는데요.

server에서 data는 제대로 가지고 오는데요, server는 하나를 두고 client를 10개 정도 실행을 해서 하니깐 server에서 아래와 같이 Exception이 걸리면서 죽습니다.

고수님들의 충고 바랍니다.

======
server
======

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.PrintWriter;

public class E_Server extends Thread{
private Socket E_Socket;
private ServerSocket E_Server_Socket;
private ServerThread E_Server_Thread;
private ArrayList Thread_List;


public E_Server(){
Thread_List = new ArrayList();
try{

E_Server_Socket = new ServerSocket(7777);
}catch(IOException e){
e.printStackTrace();
}
}

public void run(){
while(true){
try{
E_Socket = E_Server_Socket.accept();
E_Server_Thread = new ServerThread(E_Socket);
E_Server_Thread.start();
Thread_List.add(E_Server_Thread);
}catch(IOException e){
e.printStackTrace();
}
}
}

public static void main(String[] args){
new E_Server().start();
}
}

class ServerThread extends Thread{
private PrintWriter writer;
private String data;

public ServerThread(Socket E_Socket){
try{

writer = new PrintWriter(E_Socket.getOutputStream());
File file = new File("D:\\E_SERVER\\log\\Server_20090302.log");
FileReader reader = new FileReader(file);
BufferedReader bufReader = new BufferedReader(reader);
data = bufReader.readLine();
writer.println(data);
writer.flush();
writer.close();
bufReader.close();
E_Socket.close();
}catch(FileNotFoundException e){
System.out.println("파일이 존재 하지 않습니다");
}catch(IOException e){
e.printStackTrace();
}
}
}

====
MSG
====

Exception in thread "Thread-0" java.lang.OutOfMemoryError: Java heap space
at java.io.BufferedReader.
at java.io.BufferedReader.
at ServerThread.
at E_Server.run

위와 같은 msg를 남겨 놓고 죽습니다.

고수님들의 충고 부탁드립니다.

좋은 하루 되세요.

bookgekgom의 이미지

으음...

메모리가 바닦났다는데여...

ㅇㅅㅇ...

저렇게 하면 쓰레드가 10 개면 파일을 10 번 로딩하니까여...

파일은 한번만 로딩하고 보내는게 어떨까여?

그리고 저렇게 보내면 1 줄만 보내질텐데..

파일 전채를 보내는것도 좋을것 같아요.

---------------------------------------------------------------------------------------------------------------
루비 온 레일즈로 만들고 있는 홈페이지 입니다.

http://jihwankim.co.nr

여러 프로그램 소스들이 있습니다.

필요하신분은 받아가세요.

sjjloveangel의 이미지

좋은 답변 감사 합니다.

2가지 질문이 있는데요,

첫째로, 쓰레드가 1개의 파일을 10번 로딩을 하는게 메모리와 관련이 많나요??

많다면, 10번 로딩하지 않고 한번만 로딩 하는 방법 좀 알려 주세요. (쓰레드를 잘 모르겟어요)

둘째로, 1줄만 보내는 것 말고 파일 전체를 보내는 것도 server나 메모리에 문제가 생기지 않나요??

너무 초보라 부탁 드립니다. 좋은 하루 되세요.

bookgekgom의 이미지

지금 님이 하시는 방법은

각 스레드 마다 new 를 이용하여 파일을 생성하잖아요.

딱한번 new 를 이용해서 부른뒤에

각 쓰레드에 객체를 넘겨주고 사용하면 될것 같은데요.

그리고 이렇게 하면 한줄보내는거나 파일다보내는거나 그게 그거..

그리고 밑에 분이 한말도 유의하세염...

모든것이 쓰레드일 필요는 없습니다.

---------------------------------------------------------------------------------------------------------------
루비 온 레일즈로 만들고 있는 홈페이지 입니다.

http://jihwankim.co.nr

여러 프로그램 소스들이 있습니다.

필요하신분은 받아가세요.

endofhope의 이미지

1. socket 은 알아서 GC 되지 않습니다. try/catch 만 쓰셨는데 finally 에서 끊어주세요.

2. ServerThread 를 생성하면서 파일을 읽은 다음 소켓에 쓰는 부분이 있습니다.
한줄을 읽은 다음 그 내용을 member 인 data 에 저장하는데 ServerThread 자체가 Thread_List 에 들어가
있으므로 ServerThread 는 GC 되지 않습니다. 그러므로 data 는 GC 되지 않습니다.
아마 OOM 이 발생한 것도 이러한 data 가 쌓여서 발생한 듯 합니다.

3. BufferedReader 로 읽으셨는데, BufferedReader 는 내부 버퍼로 8192 를 무조건 읽어서 가지고
있습니다. 만약 writer.close 나 bufReader.close 가 불리기 전에 exception 이 발생했다면
8k 씩 쌓이게 됩니다. 역시 try/catch/ 에 finally 구문에서 확실히 끊어주세요.

4. ServerThread 클래스에 run() 이 없기 때문에 이게 굳이 thread 를 extend 할 이유는 없어 보입니다.
Thread 를 사용해야한다면 생성자가 아니라 run() 에서 해당 코드가 있다면 더 좋겠네요. 물론 member 변수인 writer 나 data 는 제거하는게 좋겠습니다.

사족 : java 는 GC 라는 좋은 기능이 있습니다만, 이게 안 되는 경우가 몇몇 있습니다.
지금 문제가 되신 socket, file 등이 바로 그것인데요,
resource 를 빌려왔으면 반드시 반환되도록 한다 라는 것만 염두에 두시면 더 좋은 코드가 될 듯 합니다.

--
말할 수 있는 것은 분명하게 말해질 수 있다;
말해질 수 없는 것에 대해서는 침묵해야한다.
논리철학논고 - 루드비히 비트겐슈타인

--
말할 수 있는 것은 분명하게 말해질 수 있다;
말해질 수 없는 것에 대해서는 침묵해야한다.
논리철학논고 - 루드비히 비트겐슈타인

bookgekgom의 이미지

추천

---------------------------------------------------------------------------------------------------------------
루비 온 레일즈로 만들고 있는 홈페이지 입니다.

http://jihwankim.co.nr

여러 프로그램 소스들이 있습니다.

필요하신분은 받아가세요.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.