线程负载过重导致内存问题

时间:2015-07-28 01:03:09

标签: java android multithreading sqlite

在logcat中,我一直看到这个:

我/艺术:背景粘性并发标记扫描GC释放141468(7MB)AllocSpace对象,3(255KB)LOS对象,25%免费,21MB / 29MB,暂停1.228ms总计132.652ms

和此:

W / art:暂停所有线程:xxx毫秒

这导致我在上次进行的最后一次Web服务方法调用中获得org.apache.http.conn.HttpHostConnectException Connection to https://plcloud.c6.ixsecure.com refused

如何停止"暂停所有线程"和重垃圾收集使用,以便我可以通过我的所有Web服务方法调用,而不会遇到内存问题?

目前它从Web服务获取数据并将其存储在本地SQLite数据库中。这是我的代码:

代码调用同步类"得到"方法(从web服务获取数据并将其保存到sqlite数据库):

class SyncThread extends Thread {
    @Override
    public void run() {
        try {
            syncHandler.sendEmptyMessage(16);
            Credentials credentials = new Credentials(usernameField
                    .getText().toString(), passwordField.getText()
                    .toString());
            UserCredentialsOut userCredentials = credentials
                    .getCredentials();

            if (userCredentials.getReturnCode() == 1) {
                Settings.getInstance().setEntityId(
                        userCredentials.getEntityId());

                syncHandler.sendEmptyMessage(1);
                CustomerSync custSync = new CustomerSync(context,
                        syncProgressDialog);
                Log.i("Customer Sync", "getCustomers");
                custSync.getCustomers(credentials);

                syncHandler.sendEmptyMessage(2);
                PetSync petSync = new PetSync(context, syncProgressDialog);
                Log.i("Pet Sync", "getPets");
                petSync.getPets(credentials);

                syncHandler.sendEmptyMessage(4);
                SystemSync systemSync = new SystemSync(context,
                        syncProgressDialog);
                Log.i("ListValues Sync", "getListValuesInitials");
                systemSync.getListValuesInitials(credentials);

                syncHandler.sendEmptyMessage(5);
                Log.i("Vets Sync", "getVets");
                systemSync.getVets(credentials);

                syncHandler.sendEmptyMessage(6);
                Log.i("Groomers Sync", "getGroomers");
                try{
                    systemSync.getGroomers(credentials);
                }catch (NullPointerException e) {
                    Log.e("NullPointerException", e.getMessage()+"benebne");
                }

                syncHandler.sendEmptyMessage(7);
                Log.i("Services Sync", "getServices");
                systemSync.getServices(credentials);

                syncHandler.sendEmptyMessage(8);
                Log.i("CalendarDays Sync", "getCalendarDays");
                systemSync.getCalendarDays(credentials);

                syncHandler.sendEmptyMessage(10);
                Log.i("loyeeUnavailTimes Sync",
                        "getEmployeeUnavailTimes");
                systemSync.getEmployeeUnavailTimes(credentials);

                syncHandler.sendEmptyMessage(12);
                Log.i("Runs Sync", "getRuns");
                systemSync.getRuns(credentials);

                syncHandler.sendEmptyMessage(14);
                Log.i("DaycareGroups Sync", "getDaycareGroups");
                systemSync.getDaycareGroups(credentials);

                syncHandler.sendEmptyMessage(3);
                OptionsSync optSync = new OptionsSync(context,
                        syncProgressDialog);
                Log.i("SystemOptions Sync", "getSystemOptions");
                SystemOptions systemOptions = optSync
                        .getSystemOptions(credentials);

                if (systemOptions != null) {

                    if (systemOptions.isModuleGroom()) {
                        syncHandler.sendEmptyMessage(9);
                        PetGroomSync petGroomSync = new PetGroomSync(
                                context, syncProgressDialog);
                        Log.i("PetGrooms Sync", "getPetGrooms");
                        petGroomSync.getPetGrooms(credentials);

                        syncHandler.sendEmptyMessage(11);
                        AppointmentSync appointmentSync = new AppointmentSync(
                                context, syncProgressDialog);
                        Log.i("Appointments Sync", "getAppointments");
                        appointmentSync.getAppointments(credentials);
                    }

                    if (systemOptions.isModuleBoard()) {
                        syncHandler.sendEmptyMessage(13);
                        AppointmentBoardSync appointmentBoardSync = new AppointmentBoardSync(
                                context, syncProgressDialog);
                        Log.i("ApptBoards Sync", "getApptBoards");
                        appointmentBoardSync.getApptBoards(credentials);
                    }

                    if (systemOptions.isModuleDaycare()) {
                        syncHandler.sendEmptyMessage(15);
                        AppointmentDaycareSync appointmentDaycareSync = new AppointmentDaycareSync(
                                context, syncProgressDialog);
                        Log.i("ApptDayCares Sync", "getApptDayCares");
                        appointmentDaycareSync.getApptDaycares(credentials);
                    }
                }

                syncHandler.sendEmptyMessage(0);
                return;
            } else {
                syncHandler.sendMessage(syncHandler.obtainMessage(-1,
                        userCredentials.getMessage()));
                return;
            }

        } catch (ClientProtocolException e) {
            Log.e("ClientProtocolException", e.toString());
        } catch (IOException e) {
            Log.e("IOException", e.toString());
        } catch (Exception e) {
            Log.e("SyncException", e.toString());
        }

        syncHandler.sendMessage(syncHandler.obtainMessage(-1,
                getString(R.string.connError)));
    }
}

一个实际的同步类 - 所有同步类大致相同,因此您只需要查看其中一个 - 注意" getCustomers"调用" initCustomersFromJson"的方法 - 这些是获取数据然后将其保存到sqlite db的部分:

public class CustomerSync implements ICustomerSync {
    public static final int QUANTITY = 0;
    private long offset;
    private ProgressDialog progressDialog;
    private Context context;
    private HttpClient client;
    private final String HTTPS_GET_CUSTOMERS = "https://plcloud.c6.ixsecure.com/PLService.svc/GetCustomers";
    private final String GET_URL = "{0}?quant={1}&offset={2}";
    private final String HTTPS_SYNC_CUSTOMERS = "https://plcloud.c6.ixsecure.com/PLService.svc/SyncCustomers";

    private CustomerSync() {
        client = new DefaultHttpClient();
    }

    public CustomerSync(Context context, ProgressDialog progressDialog) {
        this();
        this.context = context;
        this.progressDialog = progressDialog;
    }

    public Customer[] initCustomersFromJson(Credentials credentials)
            throws ClientProtocolException, IOException, URISyntaxException {
        String getUri;
        getUri = MessageFormat.format(GET_URL, HTTPS_GET_CUSTOMERS,
                QUANTITY + "", offset + "");

        credentials.initGetOAuthStructure(HTTPS_GET_CUSTOMERS);

        HttpGet request = new HttpGet(getUri + "&"
                + credentials.getOauthStructure());
        String content = client.execute(request, new BasicResponseHandler());

        Gson gson = new GsonBuilder().serializeNulls()
                .excludeFieldsWithoutExposeAnnotation().create();
        return gson.fromJson(content, Customer[].class);
    }

    @Override
    public void getCustomers(Credentials credentials)
            throws ClientProtocolException, IOException, URISyntaxException {
        ICustomerDAO customerDAO = (ICustomerDAO) DAOFactory.getDAO(
                ICustomerDAO.class.getName(), context);
        customerDAO.open();

        Customer[] customers;


            customers = initCustomersFromJson(credentials);
            progressDialog.setMax(customers.length);
            progressDialog.setProgress(0);
            customerDAO.saveCustomers(customers, progressDialog);

            if (customers.length > 0) {
                offset = customers[customers.length - 1].getId();
            }


        customerDAO.close();

        Settings.getInstance().setLastSyncCustomerDatetime(new Date());
    }

1 个答案:

答案 0 :(得分:1)

我认为如果数据非常大,那么流式传输数据会更好。我在你的代码中看到你已经使用了GSON,你可以使用GSON来传输json数据。

例如:

        String getUri;
        getUri = MessageFormat.format(GET_URL, HTTPS_GET_CUSTOMERS,
                QUANTITY + "", offset + "");

        credentials.initGetOAuthStructure(HTTPS_GET_CUSTOMERS);

        HttpGet request = new HttpGet(getUri + "&"
                + credentials.getOauthStructure());
        HttpResponse response = client.execute(request);

        Reader streamReader = new InputStreamReader(response
                    .getEntity().getContent());
        JsonReader reader = new JsonReader(streamReader);
        ArrayList<Customer> customerList = new ArrayList<Customer>();
        reader.beginArray();
        while (reader.hasNext()) {
            Customer customer = new Customer();
            reader.beginObject();
            while (reader.hasNext()) {
                String name = reader.nextName();
                if (name.equals("Action")) {
                    customer.setAction(reader.nextString());
                } else if (name.equals("Addr1")) {
                    customer.setAddr1(reader.nextString());
                } else if (name.equals("Addr2")) {
                    customer.setAddr2(reader.nextString());
                } else if (//Other condition and value)
                    ...
                } else {
                    reader.skipValue();
                }
            }
            reader.endObject();
            customerList.add(customer);
        }
        reader.endArray();
        reader.close();

使用JsonReader,您可以逐个流式传输数据并直接处理它,而不是将所有数据保存到一个数组中,然后对其进行处理,这可能会导致内存问题。