Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 17
  1. #1
    Utente di HTML.it L'avatar di morphy79
    Registrato dal
    Jun 2004
    Messaggi
    1,568

    memoria in crescita in serversocket

    ciao a tutti, ho un problema che non riesco a risolvere e non vedo dov'è l'errore..
    ho realizzato 2 semplici classi, un server socket e un socket thread che viene aperto ad ogni invocazione.. il problema è che mi aumenta sempre la memoria ad ogni invocazione..
    eppure il socket lo chiudo...
    potete darmi una mano ???

    codice:
    
    public class Service implements Globals
    {
    	private static LogHelper lh = new LogHelper();
    	private static ExceptionHelper eh = new ExceptionHelper();
    
    	/**
    	* AVVIO PRINCIPALE DEL PROGRAMMA
    	* (esecuzione in un thread indipendente perchè utilizzato come servizio windows)
    	* @param args
    	*/
    	public static void main(String[] args) 
    	{
    		Runnable r = new Runnable() {
    			public void run () {
    				try
    				{
    					Thread.sleep(1000);
    				} 
    				catch (InterruptedException e) 
    				{
    					e.printStackTrace(); // quasi impossibile, a meno che non parta il servizio
    				}
    				// avvio del thread con ciclo interno
    				executeService();
    			}
    		};
    		(new Thread (r)).start();
    	}
    	
    	/**
    	 * FUNZIONE PER L'APERTURA DEL SERVER SOCKET IN ASCOLTO SU UNA DETERMINATA PORTA
    	 */
    	private static void executeService()
    	{
    		lh.debugOperazioni(LOGGER_PREFIX, "Avvio applicazione", "Service.java", "executeService()", Level.INFO_INT);
    		
            ServerSocket serverSocket = null;
        	ParseXML parseXML = new ParseXML();
        	
        	int session = 0;
    
            try 
            {
            	// lettura della porta da file di configurazione
            	lh.debugOperazioni(LOGGER_PREFIX, "Lettura della porta da file di configurazione", "Service.java", "executeService()", Level.INFO_INT);
            	int port = Integer.parseInt(parseXML.getNodeValue(PATH_FILE_CONFIG_XML, "SERVER_PORT"));
            	
            	// apertura del socket
        		lh.debugOperazioni(LOGGER_PREFIX, "Apertura socket in corso, porta " + port, "Service.java", "executeService()", Level.INFO_INT);
    	        serverSocket = new ServerSocket(port);
    	        lh.debugOperazioni(LOGGER_PREFIX, "Apertura socket riuscita, in attesa di connessioni", "Service.java", "executeService()", Level.INFO_INT);
    	        
    	        // ciclo infinito di ascolto sulla porta
    	        while (true) 
    	        {
    	        	// ricevuta connessione, avvio in un nuovo thread la procedura di scampio dati
    	        	Socket clientSocket = serverSocket.accept();
    	        	
    	        	// incremento sessione
    	        	session = session + 1;
    	        	
    				lh.debugOperazioni(LOGGER_PREFIX, "Ricevuta nuova connessione, session number = " + session, "Service.java", "executeService()", Level.INFO_INT);
    				new ProxyThread(clientSocket, session).start();
    				
    				// reset limite massimo di sessione
    	        	if(session==Integer.MAX_VALUE)
    	        	{
    	        		session = 0;
    	        	}
    	        }
           
    		} 
            catch (IOException e)
            {
            	lh.debugOperazioni(LOGGER_PREFIX, "Java Error : " + eh.getStackTrace(e), "Service.java", "executeService()", Level.ERROR_INT);
    		}
            finally
            {
            	// chiusura del socket in caso di errore
            	try 
            	{
            		lh.debugOperazioni(LOGGER_PREFIX, "Chiusura connessione server socket", "Service.java", "executeService()", Level.INFO_INT);
    				serverSocket.close();
    			} 
            	catch (IOException e) 
            	{
    				lh.debugOperazioni(LOGGER_PREFIX, "Java Error :" + eh.getStackTrace(e), "Service.java", "executeService()", Level.ERROR_INT);
    			}
    		}
    
    	}
    	
    
    
    }
    
    
    
    public class ProxyThread extends Thread implements Globals
    {
    	
    	private static String path_reportXML = "";
    	private static Vector elenco_siti_logistici = new Vector();
    	private static Vector elenco_frontend = new Vector();
    	
    	private static LogHelper lh = new LogHelper();
    	private static ExceptionHelper eh = new ExceptionHelper();
    	private static ParseXML parseXML = new ParseXML();
    	
        private Socket socket = null;
        private int session = 0;
        
    	private DataOutputStream output = null;
    	private BufferedReader in = null;
     
        /** 
         * COSTRUTTORE
         * @param socket
         */
        public ProxyThread(Socket socket, int session) 
        {
            super("ProxyThread");
            this.socket = socket;
            this.session = session;
            initConfig();
        }
        
    	/**
    	 * FUNZIONE DI CARICAMENTO FILE DI CONFIGURAZIONE
    	 */
    	private void initConfig()
    	{
    		// lettura della porta da file di configurazione
        	lh.debugOperazioni(LOGGER_PREFIX + "ses [" + session + "]", "Lettura file di configurazione", this.getClass().getName(), "executeService()", Level.INFO_INT);
    		path_reportXML = parseXML.getNodeValue(PATH_FILE_CONFIG_XML, "PATH_REPORT_XML");
    		elenco_siti_logistici = parseXML.getSitiLogistici(PATH_FILE_CONFIG_XML, "SITI_LOGISTICI");
    		elenco_frontend = parseXML.getElencoFrontend(PATH_FILE_CONFIG_XML, "ELENCO_FRONTEND");
    	}	
    
    	
    	/* (non-Javadoc)
    	 * @see java.lang.Thread#run()
    	 */
    	public void run() 
    	{
    		try
    		{
    			// preparo gli stream
    			in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
    			output = new DataOutputStream(socket.getOutputStream());
    			
    			// recupero la request
    			String urlRequest = readRequest();
    			lh.debugOperazioni(LOGGER_PREFIX + "ses [" + session + "]", "Richiesta Url : " + urlRequest, this.getClass().getName(), "run()", Level.INFO_INT);
    
    			// preparo report
    			lh.debugOperazioni(LOGGER_PREFIX + "ses [" + session + "]", "Apertura Report", this.getClass().getName(), "run()", Level.INFO_INT);
    			ReportVerify report = new ReportVerify();
    			
    			// recupero frontend
    			FrontEndBean frontend = getFrontendFromUrl(urlRequest);
    			lh.debugOperazioni(LOGGER_PREFIX + "ses [" + session + "]", "Frontend identificato : '" + frontend.getHost() + ":" + frontend.getPort()+ "'", this.getClass().getName(), "run()", Level.INFO_INT);
    			
    			// recupero sito
    			SitoLogistico sitoLogistico = getSitoFromUrl(urlRequest);
    			lh.debugOperazioni(LOGGER_PREFIX + "ses [" + session + "]", "Sito Logistico identificato : '" + sitoLogistico.getDescrizione() + "(" + sitoLogistico.getCodice() + ")'", this.getClass().getName(), "run()", Level.INFO_INT);
    			
    			// inoltro verifica
    			if(!frontend.getHost().equals("") && !sitoLogistico.getCodice().equals(""))
    			{
    				new Ordini(frontend, sitoLogistico, session, report).inviaPreOrdine();
    			}
    
    			// inoltro risposta
    			writeHtmlResponse(report.getReportDocument());
    		}
    		catch(Exception e)
    		{
    			lh.debugOperazioni(LOGGER_PREFIX + "ses [" + session + "]", "Java Error :" + eh.getStackTrace(e), this.getClass().getName(), "run()", Level.ERROR_INT);
    		}
    		finally
    		{
    			closeStream();
    		}
    		
    	}
    
    	/**
    	 * FUNZIONE PER IL RECUPERO DEL FRONTEND DALL'URL RICEVUTO
    	 * @return
    	 */
    	private FrontEndBean getFrontendFromUrl(String urlRequest)
    	{
    		FrontEndBean returnFrontend = new FrontEndBean();
    		FrontEndBean frontendTemp = new FrontEndBean();
    		String searchParam = "f=";
    		
    		// recupero il parametro relativo al frontend
    		String paramFrontend = getParameter(urlRequest, searchParam);
    		
    		// ciclo per ogni frontend
    		lh.debugOperazioni(LOGGER_PREFIX + "ses [" + session + "]", "Avvio ciclo frontend", "Run.java", "main()", Level.INFO_INT);
    		for(int i_frontend=0;i_frontend<elenco_frontend.size();i_frontend++)
    		{
    			// recupero frontend temp
    			frontendTemp = (FrontEndBean)elenco_frontend.elementAt(i_frontend);
    			
    			// se il frontend corrisponde a quello ricevuto come parametro
    			if(frontendTemp.getHost().equalsIgnoreCase(paramFrontend))
    			{
    				returnFrontend = frontendTemp;
    				break;
    			}
    		}
    		return returnFrontend;
    	}
    	
    	/**
    	 * FUNZIONE PER IL RECUPERO DEL SITO LOGISTICO DALL'URL RICEVUTO
    	 * @return
    	 */
    	private SitoLogistico getSitoFromUrl(String urlRequest)
    	{
    		SitoLogistico returnSito = new SitoLogistico();
    		SitoLogistico sitoTemp = new SitoLogistico();
    		String searchParam = "s=";
    		
    		// recupero il parametro relativo al sito logistico
    		String paramSito = getParameter(urlRequest, searchParam);
    		
    		// ciclo per ogni sito logistico
    		lh.debugOperazioni(LOGGER_PREFIX + "ses [" + session + "]", "Avvio ciclo siti logistici", "Run.java", "main()", Level.INFO_INT);
    		for(int i_siti=0;i_siti<elenco_siti_logistici.size();i_siti++)
    		{
    			// recupero sito temp
    			sitoTemp = (SitoLogistico)elenco_siti_logistici.elementAt(i_siti);
    			
    			// se il sito corrisponde a quello ricevuto come parametro
    			if(sitoTemp.getCodice().equalsIgnoreCase(paramSito))
    			{
    				returnSito = sitoTemp;
    				break;
    			}
    		}
    		return returnSito;
    	}
    	
    	/**
    	 * FUNZIONE PER IL RECUPERO DI UN PARAMETRO DALL'URL RICEVUTO
    	 * @return
    	 */
    	private String getParameter(String urlRequest, String searchParam)
    	{
    		String parameterFound = "";
    		
    		// recupero elenco parametri
    		String[] parameters = getUrlParameters(urlRequest);
    		
    		// se sono stati rilevati dei parametri
    		if(parameters!=null)
    		{
    			// ricerco tra i parametri
    			for(int i_param=0;i_param<parameters.length;i_param++)
    			{
    				String parameterTemp = parameters[i_param];
    				// se rilevo il parametro che fa riferimento alla stringa di ricerca
    				int indexTemp = parameterTemp.indexOf(searchParam);
    				if(indexTemp>-1)
    				{
    					// recupero il valore del parametro (da dopo la stringa di ricerca)
    					parameterFound = parameterTemp.substring(indexTemp+searchParam.length());
    					break;
    				}
    				
    			}
    		}
    		return parameterFound;
    	}
    	
    	/**
    	 * FUNZIONE PER IL RECUPERO DELL'ELENCO PARAMETRI DALL'URL RICEVUTO
    	 * @return
    	 */
    	private String[] getUrlParameters(String urlRequest)
    	{
    		String page = "verify?";
    		int indexParameters = urlRequest.indexOf(page);
    		if(indexParameters == -1 )
    		{
    			return null;
    		}
    		String params[] = urlRequest.substring(indexParameters + page.length()).split("&");
    		return params;
    	}
    	
        /**
         * FUNZIONE PER LA LETTURA DELLA REQUEST
         * @return
         * @throws IOException 
         */
        private String readRequest() throws IOException 
        {
        	String urlRequest = "";
    		String inputLine = in.readLine();
    		String[] tokens = inputLine.split(" ");
    		urlRequest = tokens[1];
    		return urlRequest;
    	}
        
        
    	/**
    	 * FUNZIONE PER LA SCRITTURA DELLA RESPONSE
    	 * @throws IOException 
    	 */
    	private void writeHtmlResponse(String responseText) throws IOException 
    	{
    		output.writeBytes("HTTP/1.1 200 OK\r\n");
    		output.writeBytes("Content-Type: text/html\r\n\r\n");
    		output.writeBytes("<html><head></head><body>RESULT_CHECK=" + responseText +  "</body></html>");
    		output.flush();
    	}
    	
    	
    	private void closeStream()
    	{
    		try 
    		{
    			in.close();
    		} 
    		catch (IOException e) 
    		{
    			lh.debugOperazioni(LOGGER_PREFIX + "ses [" + session + "]", "Java Error :" + eh.getStackTrace(e), this.getClass().getName(), "close()", Level.WARN_INT);
    		}
    		
    		try 
    		{
    			output.close();
    		} 
    		catch (IOException e) 
    		{
    			lh.debugOperazioni(LOGGER_PREFIX + "ses [" + session + "]", "Java Error :" + eh.getStackTrace(e), this.getClass().getName(), "close()", Level.WARN_INT);
    		}
    		
    		try 
    		{
    			socket.close();
    		} 
    		catch (IOException e) 
    		{
    			lh.debugOperazioni(LOGGER_PREFIX + "ses [" + session + "]", "Java Error :" + eh.getStackTrace(e), this.getClass().getName(), "close()", Level.WARN_INT);
    		}
    	}
    	
    }
    odio chi parla di politica..
    anzi vorrei fondare un partito contro tutto ciò

  2. #2

    Re: memoria in crescita in serversocket

    Originariamente inviato da morphy79
    ciao a tutti, ho un problema che non riesco a risolvere e non vedo dov'è l'errore..
    ho realizzato 2 semplici classi, un server socket e un socket thread che viene aperto ad ogni invocazione.. il problema è che mi aumenta sempre la memoria ad ogni invocazione..
    eppure il socket lo chiudo...
    potete darmi una mano ???
    Prima di tutto l'aumento di memoria c'è l'hai sul server o sul Client ?
    Premetto che non ho letto tutto il codice per capire se c'è un memory leak da qualche parte
    Che tu chiuda il socket è una cosa buona ma non è detto che in quel momento tutte le risorse allocate in memoria per quel socket vengano rilasciate. Esse infatti verranno rilasciate quando la VM richiamerà il GC (Garbage Collector).
    Di quanto di aumenta la memoria ?

  3. #3
    Utente di HTML.it L'avatar di morphy79
    Registrato dal
    Jun 2004
    Messaggi
    1,568
    la memoria mi aumenta di 8000 kb più o meno.. è parecchio
    ho provato ad invocare il garbage collector a mano dopo la chiusura del socket (lo so è sconsigliato) ma non cambia molto..
    la memoria aumenta, molto meno, 1000kb ma aumenta..
    odio chi parla di politica..
    anzi vorrei fondare un partito contro tutto ciò

  4. #4
    Richiamare il GC da codice oltre che sconsigliato non implica che esso parta quando lo dici tu.
    Non hai risposto se la memoria ti aumenta lato client o lato server ?
    Anche se suppongo che sia lato server.
    Cmq l'aumento di 8 mega byte non mi sembra cosi eccessivo, eventualmente limando un pò il codice si può scendere ma non vedo proprio se valga la pena.
    Il problema è capire se una volta arrivato al massimo Heap size questa venga rilasciata oppure no, anche se come hai detto tu richiamando il gc questa sembrerebbe che venga rilasciata.

  5. #5
    Utente di HTML.it L'avatar di morphy79
    Registrato dal
    Jun 2004
    Messaggi
    1,568
    qui mi perdo.. in che senso ? da task manager ho un processo relativo al mio applicativo ServerSocket, quindi mi vien da dirti lato server ma non vorrei dire cavolate
    odio chi parla di politica..
    anzi vorrei fondare un partito contro tutto ciò

  6. #6
    Se hai un Server Socket da qualche altra parte avrai anche un client che si connette ad esso.
    Il codice postato mi sembra che sia solo la parte server dell'applicativo.

  7. #7
    Utente di HTML.it L'avatar di morphy79
    Registrato dal
    Jun 2004
    Messaggi
    1,568
    ah si ok.. ma dall'altra parte metto semplicemente un indirizzo sul browser..
    la memoria aumenta proprio lato server !!
    odio chi parla di politica..
    anzi vorrei fondare un partito contro tutto ciò

  8. #8
    Utente di HTML.it
    Registrato dal
    Sep 2012
    Messaggi
    707
    Aggiungo una cosa a latere che non c'entra con il problema.

    È inutile fare in queste due righe "new Vector" se poi sovrascrivi il valore in initConfig:
    private static Vector elenco_siti_logistici = new Vector();
    private static Vector elenco_frontend = new Vector();

    Ciao.

  9. #9
    Riguardando un pochino il codice mi sembra che fai un uso smodato della parola static tra l'altro anche private, ciò vuol dire che non ti serve a molto o cmq può essere traquillamente omessa creado un un bel get per queste proprietà.
    Inoltre "static" di solito andrebbe usato con moderazione come preved l'OOP, inoltre a gestione della allocazione e successivo rilascio della memoria degli oggetti static è un pò problematica. Nel resto del codice postato non mi sembra che ci siano altri memory leak evidenti. Andrebbe eventualmente lanciato con un buon profiler in modo da vedere dove è il collo di bottiglia.

  10. #10
    Utente di HTML.it L'avatar di morphy79
    Registrato dal
    Jun 2004
    Messaggi
    1,568
    si gli static li ho tolti erano rimasti da un copia incolla..
    anche i vector..
    vi ringrazio entrambi del suggerimento..

    invece per il profiler non so cos'è... hai un qualche link dove posso istruirmi su questa cosa ?
    non ne so assolutamente nulla e sembra interessante
    grazie
    odio chi parla di politica..
    anzi vorrei fondare un partito contro tutto ciò

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.