背景下的粘性并发标记清除GC释放

31

我有一个应用程序,每10秒钟检查一次数据库是否有新数据,如果有,它将获取它并停止检查数据库。

我已经实现了一个文本观察器来检查文本框是否为空。如果是,它会检查数据库,如果它包含任何文本,就会停止。

这是我的代码:

 @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    txtBoxUser.addTextChangedListener(checkUserRent);

    getData();
}


//TEXTWATCHER FOR GETTING PERSON WHO RENTED BOX
private final TextWatcher checkUserRent = new TextWatcher() {
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
    }

    public void onTextChanged(CharSequence s, int start, int before, int count) {
    }
    public void afterTextChanged(Editable s) {
        if (s.length() == 0) {
            check();
        } else {
            Toast.makeText(MainActivity.this, "STOP",
                    Toast.LENGTH_LONG).show();
        }
    }
};


public void start(View view)
{
    getData();
}

public void cancel(View view)
{
    txtBoxUser.setText("");
    txtBoxPasscode.setText("");
}

private void getData(){

  final String id = txtBoxName.getText().toString().trim();

    class GetEmployee extends AsyncTask<Void,Void,String>{
        ProgressDialog loading;
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
       //     loading = ProgressDialog.show(MainActivity.this,"Fetching...","Wait...",false,false);
        }

        @Override
        protected void onPostExecute(String s) {
            super.onPostExecute(s);
      //      loading.dismiss();
            showEmployee(s);
        }

        @Override
        protected String doInBackground(Void... params) {
            RequestHandler rh = new RequestHandler();
            String s = rh.sendGetRequestParam(DATA_URL,id);
            return s;
        }
    }
    GetEmployee ge = new GetEmployee();
    ge.execute();
}

private void showEmployee(String json){
    try {
        JSONObject jsonObject = new JSONObject(json);
        JSONArray result = jsonObject.getJSONArray(JSON_ARRAY);
        JSONObject c = result.getJSONObject(0);
        String name = c.getString(GET_BOXUSER);
        String desg = c.getString(GET_PASSCODE);

        txtBoxUser.setText(name);
        txtBoxPasscode.setText(desg);

    } catch (JSONException e) {
        e.printStackTrace();
    }
}


private void check()
{
    getData();

}

但是在等待数据时,我在logcat中看到了这个。我只是想知道这样做是否安全或正常?

I/art: Background sticky concurrent mark sweep GC freed 5614(449KB) AllocSpace objects, 18(288KB) LOS objects, 33% free, 1691KB/2MB, paused 5.354ms total 10.731ms
I/art: Background sticky concurrent mark sweep GC freed 7039(557KB) AllocSpace objects, 22(352KB) LOS objects, 39% free, 1561KB/2MB, paused 10.554ms total 15.931ms 
I/art: Background partial concurrent mark sweep GC freed 7279(564KB) AllocSpace objects, 21(336KB) LOS objects, 40% free, 1504KB/2MB, paused 5.721ms total 15.823ms
I/art: WaitForGcToComplete blocked for 5.375ms for cause HeapTrim
I/art: Background partial concurrent mark sweep GC freed 7650(591KB) AllocSpace objects, 22(352KB) LOS objects, 40% free, 1505KB/2MB, paused 5.511ms total 21.465ms
3个回答

45

这是完全正常的。它意味着您正在使用内存,然后由垃圾回收器释放。唯一的问题是如果您用尽了内存,或者由于垃圾回收而出现性能问题。但这不是您需要赶紧修复的内容。


2
那么,如何解决这个问题?我在编辑文本框时遇到了同样的情况。 - Pir Fahim Shah
1
@GeorgySavatkov 没有问题,因此没有什么需要解决的。一些算法/应用程序只是使用内存。如果没有性能问题,那就完全没有问题。 - Gabe Sechan
8
我的应用会卡顿几秒钟,因为出现了这种情况。请提供解决方案。 - Sreekanth Karumanaghat
请查看此链接:https://dev59.com/0-o6XIcBkEYKwwoYIAcL - elirigobeli

4

我曾经遇到过类似的问题。你的代码可以正常工作,但如果处理时间太长,应用程序可能会出现“应用无响应”错误并关闭。这也破坏了使用AsyncTask的目的。

问题在于您的AsyncTask包含一个TextView,因此在执行期间会阻止任何其他操作。要解决此问题,请使您的AsyncTask是静态的,并将引用传递给TextView。然后将其存储在WeakReference中。

static class GetEmployee extends AsyncTask<Void,Void,String>{

    WeakReference<TextView> textUserWeakReference;
    WeakReference<TextView> textPassWeakReference;
    GetEmployee(TextView textUser, TextView textPass) {
        textUserWeakReference = new WeakReference<>(textUser);
        textPassWeakReference = new WeakReference<>(textPass);
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
   //     loading = ProgressDialog.show(MainActivity.this,"Fetching...","Wait...",false,false);
    }

    @Override
    protected void onPostExecute(String s) {
        super.onPostExecute(s);
  //      loading.dismiss();
        TextView textUser = textUserWeakReference.get();
        TextView textPass = textPassWeakReference.get();
        if(textView != null && textPass != null)
            showEmployee(s, textUser, textPass);
    }

    @Override
    protected String doInBackground(Void... params) {
        RequestHandler rh = new RequestHandler();
        String s = rh.sendGetRequestParam(DATA_URL,id);
        return s;
    }
}
private static void showEmployee(String json, TextView txtBoxUser, TextView txtBoxPassCode){
try {
    JSONObject jsonObject = new JSONObject(json);
    JSONArray result = jsonObject.getJSONArray(JSON_ARRAY);
    JSONObject c = result.getJSONObject(0);
    String name = c.getString(GET_BOXUSER);
    String desg = c.getString(GET_PASSCODE);

    txtBoxUser.setText(name);
    txtBoxPasscode.setText(desg);

} catch (JSONException e) {
    e.printStackTrace();
}
}

0

我曾经遇到过同样的问题,它是由一个无限循环引起的。这导致我的应用程序崩溃。

我找到了这个无限循环,将其删除,现在应用程序不再崩溃,也不会再出现这些日志了。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接