He tratado de optimizar el (memoria) de mi programa, pero todavía está GC por lo que es lag

raghav:

He escrito una pieza de software en Java que comprueba si los proxies funcionan mediante el envío de una petición HTTP usando el proxy.

Se tarda alrededor de 30.000 servidores proxy desde una base de datos, a continuación, intenta comprobar si están en funcionamiento. Los poderes recibidos de la base de datos utilizada para ser devueltos como ArrayList<String>, pero no se han cambiado a Deque<String>por las razones expuestas a continuación.

El funcionamiento del programa es que hay un ProxyRequestobjeto que almacena la IP y el puerto como una cadena y int respectivamente. El ProxyRequestobjeto tiene un método isWorkingProxy()que trata de enviar una solicitud utilizando un proxy y devuelve un booleansobre si se ha realizado correctamente.

Este ProxyRequestobjeto se envuelve alrededor de un RunnableProxyRequestobjeto que las llamadas super.isWorkingProxy()en la overrided run()método. Sobre la base de la respuesta de super.isWorkingProxy(), el RunnableProxyRequestobjeto actualiza una base de datos MySQL.

Ten en cuenta que la actualización de la base de datos MySQL es synchronized().

Se ejecuta en 750 hilos utilizando un FixedThreadPool (en un VPS), pero hacia el final, se hace muy lenta (pegado en ~ 50 hilos), lo que obviamente implica la basura colector está funcionando. Este es el problema.

He intentado lo siguiente para mejorar el retraso, no parece que el trabajo:

1) Usando un Deque<String>proxies y usar Deque.pop()para obtener la Stringen la que el proxy es. Este (creo), hace continuamente el Deque<String>más pequeño, lo que debería mejorar retraso causado por la GC.

2) Ajuste el con.setConnectTimeout(this.timeout);, donde this.timeout = 5000;De esta manera, la conexión debe devolver un resultado en 5 segundos. Si no, el hilo se ha completado y ya no debe ser activo en el subprocesos.

Además de esto, no sé de ninguna otra manera que puedo mejorar el rendimiento.

¿Alguien puede recomendar una manera para mí para mejorar el rendimiento que deben evitarse / parada quedando hacia el final de los hilos de la GC? Sé que es una pregunta sobre este Stackoverflow ( hebras Java más lento hacia el final del proceso ), pero he intentado todo en la respuesta y no ha funcionado para mí.

Gracias por tu tiempo.

Fragmentos de código:

Loop adición de hilos a la FixedThreadPool:

//This code is executed recursively (at the end, main(args) is called again)
//Create the threadpool for requests
//Threads is an argument that is set to 750.
ThreadPoolExecutor executor = (ThreadPoolExecutor)Executors.newFixedThreadPool(threads);
Deque<String> proxies = DB.getProxiesToCheck();

while(proxies.isEmpty() == false) {
    try {
        String[] split = proxies.pop().split(":");

        Runnable[] checks = new Runnable[] {
            //HTTP check
            new RunnableProxyRequest(split[0], split[1], Proxy.Type.HTTP, false),
            //SSL check
            new RunnableProxyRequest(split[0], split[1], Proxy.Type.HTTP, true),
            //SOCKS check
            new RunnableProxyRequest(split[0], split[1], Proxy.Type.SOCKS, false)
            //Add more checks to this list as time goes...
        };

        for(Runnable check : checks) {
            executor.submit(check);
        }

    } catch(IndexOutOfBoundsException e) {
        continue;
    }
}

ProxyRequest clase:

//Proxy details
private String proxyIp;
private int proxyPort;
private Proxy.Type testingType;

//Request details
private boolean useSsl;

public ProxyRequest(String proxyIp, String proxyPort, Proxy.Type testingType, boolean useSsl) {
    this.proxyIp = proxyIp;
    try {
        this.proxyPort = Integer.parseInt(proxyPort);
    } catch(NumberFormatException e) {
        this.proxyPort = -1;
    }
    this.testingType = testingType;
    this.useSsl = useSsl;
}

public boolean isWorkingProxy() {
    //Case of an invalid proxy
    if(proxyPort == -1) {
        return false;
    }

    HttpURLConnection con = null;

    //Perform checks on URL
    //IF any exception occurs here, the proxy is obviously bad.
    try {
        URL url = new URL(this.getTestingUrl());
        //Create proxy
        Proxy p = new Proxy(this.testingType, new InetSocketAddress(this.proxyIp, this.proxyPort));
        //No redirect
        HttpURLConnection.setFollowRedirects(false);
        //Open connection with proxy
        con = (HttpURLConnection)url.openConnection(p);
        //Set the request method
        con.setRequestMethod("GET");
        //Set max timeout for a request.
        con.setConnectTimeout(this.timeout);
    } catch(MalformedURLException e) {
        System.out.println("The testing URL is bad. Please fix this.");
        return false;
    } catch(Exception e) {
        return false;
    }

    try(
            BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
            ) {

        String inputLine = null; StringBuilder response = new StringBuilder();
        while((inputLine = in.readLine()) != null) {
            response.append(inputLine);
        }

        //A valid proxy!
        return con.getResponseCode() > 0;

    } catch(Exception e) {
        return false;
    }
}

RunnableProxyRequest clase:

public class RunnableProxyRequest extends ProxyRequest implements Runnable {


    public RunnableProxyRequest(String proxyIp, String proxyPort, Proxy.Type testingType, boolean useSsl) {

        super(proxyIp, proxyPort, testingType, useSsl);

    }

    @Override
    public void run() {

        String test = super.getTest();

        if(super.isWorkingProxy()) {

            System.out.println("-- Working proxy: " + super.getProxy() + " | Test: " +  test);

            this.updateDB(true, test);

        } else {
            System.out.println("-- Not working: " + super.getProxy() + " | Test: " +  test);

            this.updateDB(false, test);
        }   


    }

    private void updateDB(boolean success, String testingType) {
        switch(testingType) {
            case "SSL":
                DB.updateSsl(super.getProxyIp(), super.getProxyPort(), success);
                break;
            case "HTTP":
                DB.updateHttp(super.getProxyIp(), super.getProxyPort(), success);
                break;
            case "SOCKS":
                DB.updateSocks(super.getProxyIp(), super.getProxyPort(), success);
                break;
            default:
                break;
        }
    }
}

DB clase:

//Locker for async 
private static Object locker = new Object();

private static void executeUpdateQuery(String query, String proxy, int port, boolean toSet) {
    synchronized(locker) {
        //Some prepared statements here.
    }
}
raghav:

Gracias a Peter Lawrey por guiarme a la solución! :)
Su comentario:

@ILoveKali he encontrado bibliotecas de red no son lo suficientemente agresivo en el cierre de una conexión cuando las cosas van realmente mal. Tiempos de espera tienden a trabajar mejor cuando la conexión está muy bien. YMMV

Así que hice un poco de investigación, y se encontró que tenía que utilizar también el método setReadTimeout(this.timeout);. Anteriormente, sólo estaba usando setConnectTimeout(this.timeout);!

Gracias a este post ( HttpURLConnection de tiempo de espera por defecto ) que explicaban la siguiente:

Por desgracia, en mi experiencia, parece que el uso de estos valores por defecto puede conducir a un estado inestable, dependiendo de lo que suceda con su conexión al servidor. Si utiliza un HttpURLConnection y no establece explícitamente (por lo menos) los tiempos de espera de lectura, su conexión puede entrar en un estado permanente rancio. Por defecto. Así que siempre establecer setReadTimeout a "algo" o es posible que las conexiones huérfanas (y posiblemente hilos dependiendo de cómo se ejecuta la aplicación).

Así que la respuesta final es: El GC estaba haciendo muy bien, no era responsable del retraso. Los hilos fueron simplemente pegados siempre a un solo número, porque no se estableció el tiempo de espera de lectura, por lo que el isWorkingProxy()método nunca consiguieron un resultado y siguió leyendo.

Supongo que te gusta

Origin http://43.154.161.224:23101/article/api/json?id=182137&siteId=1
Recomendado
Clasificación