Jakiś czas temu w ramach nauki postanowiłem spróbować napisać serwer pośredniczący pomiędzy użytkownikiem a bazą danych. Na chwilę obecną zakończyłem pisanie wszystkich podstawowych funkcjonalności jednak przy testach zauważyłem dziwne zapotrzebowanie na pamięć(około 1 GB), rozpocząłem testowanie. Po kilku testach doszedłem do tego, że pamięć obciąża fragment kodu odpowiadający za wysyłanie do klienta ciągu znaków który odpowiada za jego weryfikacje. W temacie dodałem słowo dziwne, ponieważ dopóki serwer ma 2 wątki na których może przyjmować wnioski klienta o uaktualnienie ciągu znaków aplikacja nie zajmuje więcej niż 20MB pamięci, jednak gdy zainicjowany zostanie 3 wątek poziom zajmowanej pamięci wzrasta do około 1GB. 3 wątki posiadają jednakowy kod róznią się jedynie porty na których przyjmują połączenia.
Klasa w której inicjowany jest nowy wątek:
public class BasicsServices{
//VAR
private static Runnable runnableIDsender, runnableinstructionslistener, runnablesIDgen, runnablestatuschecker;
private static Thread threadIDsender0,threadIDsender1,threadIDsender2,threadinstructionslistener, threadsIDgen, threadstatuschecker;
private static int portH=15020;
//VAR-END
//CON
//CON-END
//MET
public static void servicesIDgenStart(){
runnablesIDgen = new sIDgen();
threadsIDgen = new Thread(runnablesIDgen);
threadsIDgen.start();
}
public static void servicesIDsenderStart(){ <---------- metoda odpowiadająca za
runnableIDsender = new PresIDsender0(portH); inicjowanie klasy otwierającej polączenia
threadIDsender0 = new Thread(runnableIDsender);
threadIDsender0.start();
getport();
runnableIDsender = new PresIDsender0(portH);
threadIDsender1 = new Thread(runnableIDsender);
threadIDsender1.start();
getport();
runnableIDsender = new PresIDsender0(portH);
threadIDsender2 = new Thread(runnableIDsender);
threadIDsender2.start();
}
public static void serviceInstructionsListenerStart(){
runnableinstructionslistener = new InstructionsListener();
threadinstructionslistener = new Thread(runnableinstructionslistener);
threadinstructionslistener.start();
}
public static void serviceStatusCheckerStart(){
runnablestatuschecker = new StatusChecker();
threadstatuschecker = new Thread(runnablestatuschecker);
threadstatuschecker.start();
}
private static int getport(){
if(portH==15020){
portH=15021;
return 15021;}
if(portH==15021){
portH=150022;
return 15022;}
return 0;
}
//MET-END
}
Kod odpowiadający za utworzenie połączenia z klientem, klasa wywoływana w klasie którą widać wyżej(BasicServices)
import java.net.ServerSocket;
import java.net.Socket;
public class PresIDsender0 implements Runnable{
private int port;
public PresIDsender0(int port){
this.port=port;
}
public void run(){
while(true){
try {
ServerSocket serverSocket = new ServerSocket(port);
Socket sock= serverSocket.accept();
new sIDsender(sock, port).start();
}catch(Exception e){}
}
}
}
Kod bezpośrednio odpowiadający za identyfikowanie klienta i wysyłanie stosownej odpowiedzi
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class sIDsender extends Thread implements Runnable{
private String typoperacji, idoperacji, user, privateid, sid;
private int port;
private Socket sock;
public sIDsender(Socket klientsocket,int portS){
this.sock=klientsocket;
this.port=portS+10;
}
public void run(){
String privateid, sid;
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(sock.getInputStream()));
idoperacji=reader.readLine();
user=reader.readLine();
privateid=reader.readLine();
sid=sIDgen.getsID();
reader.close();
sock.close();
if(sid.equals(sIDgen.getsID())&&privateid.equals(LoggingIn.getPrivateId(user ,true))){
ServerSocket serverSocket = new ServerSocket(port+10);
Socket socket = serverSocket.accept();
PrintWriter writer = new PrintWriter(socket.getOutputStream(), true);
writer.println(LoggingIn.getPrivateId(user ,true));
writer.println(sIDgen.getsID());
LoggingIn.setStatus(socket.getRemoteSocketAddress().toString().substring(1,socket.getRemoteSocketAddress().toString().indexOf(":")));
writer.close();
socket.close();
serverSocket.close();
}
if(sid.equals(sIDgen.getsIDlast())&&privateid.equals(LoggingIn.getPrivateId(user ,true))){
ServerSocket serverSocket = new ServerSocket(port+10);
Socket socket = serverSocket.accept();
PrintWriter writer = new PrintWriter(socket.getOutputStream(), true);
writer.println(LoggingIn.getPrivateId(user ,true));
writer.println(sIDgen.getsID());
LoggingIn.setStatus(socket.getRemoteSocketAddress().toString().substring(1,socket.getRemoteSocketAddress().toString().indexOf(":")));
writer.close();
socket.close();
serverSocket.close();
}
}catch(Exception e){}
}
}