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);
		}
	}
	
}