Chr*_*r A 10 java android memory-leaks
我想首先说这是我第一次处理性能,因为这是我第一次开发Android应用程序.
该应用程序是一个源代码编辑器,您可以在其中打开文件,修改它们并将其保存回来.该应用程序由4部分组成:
完成基本代码编辑器后,我转到语法高亮.现在,我想明确表示即使没有语法突出显示也会产生泄漏,所以这不是问题所在.
无论如何,通过测试语法highlithing,我打开"大"文件(1200行代码),我注意到应用程序变得非常慢,这是显而易见的,因为我正在整理整个文本(我将通过仅突出显示来避免这种情况)可见的文字).这促使我测试应用程序没有语法高度大文件,我发现应用程序变得有点慢,我发现一些内存泄漏发生.
特别是,当我打开一个大文件(1200行代码)时,应用程序需要1秒钟才能在textview中显示代码行,当我输入字符的绘图时速度很慢.此外,每当我键入删除字符时,都会发生内存泄漏.
我试图检查堆(使用MAT),但正如我所说,我没有任何经验,我不知道如何调查这个问题.对不起,我无法上传截图(没有stackoverflow的权限),但我可以报告一些数字:


问题1

细节:

问题2

问题3





问题1:
细节:

问题2:

问题3问题4



从Android设备监视器:


分配的一些部分:
先感谢您
编辑:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/codeScrollView"
android:fillViewport="true">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:background="@drawable/lines_stroke"
android:textColor="@android:color/white"
android:text="@string/first_line"
android:textSize="15dp"
android:gravity="right"
android:paddingLeft="15dp"
android:paddingRight="5dp"
android:id="@+id/edit_code_lines_view"/>
<com.example.green.bachelorproject.customViews.codeEditView.TouchEditText
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@drawable/code_stroke"
android:gravity="top"
android:textColor="@android:color/white"
android:textSize="15dp"
android:paddingLeft="3dp"
android:paddingRight="3dp"
android:textCursorDrawable="@color/white"
android:id="@+id/edit_code_content_view"/>
</LinearLayout>
</ScrollView>
Run Code Online (Sandbox Code Playgroud)
编辑
好的,我发现了这个问题.如果你看到,每次输入内容时,我都会更新EditText行,因为文本很长(1200行),所以需要一段时间来重新计算它.事情虽然关于那个!我必须找到一种更快的方式来显示代码行.一种选择是为每一行使用一个TextView,这样我只更新需要更改的TextView.但我不知道是否有1200个TextView对象是好的.
package com.example.green.bachelorproject.customViews.codeEditView;
import android.content.Context;
import android.graphics.Color;
import android.graphics.Typeface;
import android.text.Editable;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
import android.text.TextWatcher;
import android.text.style.ForegroundColorSpan;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
import utils.Colorizer;
import utils.Lexer;
import com.example.green.bachelorproject.events.UpdateCacheFileEvent;
import com.example.green.bachelorproject.R;
import de.greenrobot.event.EventBus;
import com.example.green.bachelorproject.internalFileSystem.InternalFile;
import java.util.ArrayList;
/**
* Created by Green on 26/02/15.
*/
public class CodeEditView extends LinearLayout {
private Context context;
private TextView lines;
private EditText code;
private Typeface currentTypeface;
private InternalFile internalFile;
private Lexer lexer;
private Colorizer colorizer;
public CodeEditView(Context context) {
super(context);
this.context = context;
init(null);
}
public CodeEditView(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
init(attrs);
}
private void init(AttributeSet attrs) {
//CHECK THIS
LayoutInflater layoutInflater = (LayoutInflater) this.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
layoutInflater.inflate(R.layout.edit_code_layout, this);
// this.colorizer = new Colorizer();
// this.colorizer.setColor("String", Color.rgb(218, 220, 95));
// this.colorizer.setColor("Number", Color.rgb(173, 125, 255));
// this.colorizer.setColor("Character", Color.rgb(218, 220, 95));
// this.colorizer.setColor("Operator", Color.rgb(234, 38, 116));
// this.colorizer.setColor("Keyword", Color.rgb(234, 38, 116));
// this.colorizer.setColor("Identifier", Color.WHITE);
// this.colorizer.setColor("Type", Color.rgb(105, 216, 238));
// this.colorizer.setColor("Comment", Color.rgb(117, 113, 91));
this.lexer = new Lexer();
this.lines = (TextView) findViewById(R.id.edit_code_lines_view);
//this.lines.setTypeface(currentTypeface);
this.code = (EditText) findViewById(R.id.edit_code_content_view);
//this.code.setTypeface(currentTypeface);
this.code.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
// writeToFile();
//EventBus.getDefault().post(new UpdateCacheFileEvent(code.getText().toString(), internalFile));
//setLines();
}
});
}
private void setLines() {
int usedLines = code.getLineCount();
String text = "1" + System.lineSeparator();
for(int i = 2; i tokens = lexer.tokenize(content);
// SpannableStringBuilder text = new SpannableStringBuilder(content);
//
// for(Lexer.Token t: tokens) {
// text.setSpan(new ForegroundColorSpan(colorizer.getColor(t)), t.start, t.end, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
// }
// code.setText(text);
// code.post(new Runnable() {
// @Override
// public void run() {
// setLines();
// }
// });
}
public void setFont(Typeface typeFace) {
this.lines.setTypeface(typeFace);
this.code.setTypeface(typeFace);
}
}
编辑:除了最近的发现,没有语法突出显示键入速度很快,但在启用语法高亮时我仍然遇到延迟.当我打开文件时,突出显示非常快,但输入仍然很慢并且内存泄漏消息
04-28 04:49:58.119:D/dalvikvm(2437):GC_EXPLICIT释放185K,17%自由6027K/7244K,暂停1ms + 1ms,总计5ms
出现.无论如何,我想知道对象1字节数组(byte [],boolean [])是什么,因为它实际上使用2 MB.有什么建议?
编辑:
绝对找到了问题所在.由于文件很大并且创建了很多跨度,当我在文件顶部更改某些内容时,editext必须重新计算所有跨度的位置.
许多其他人也面临着同样的问题。这里有一些提示:
\n\n来自代码忍者:
\n\n\n\n\n那么\xe2\x80\x99s 的实际解决方案是什么呢?避免在RelativeLayout 中使用EditText,而使用LinearLayout。根据 James 的说法,如果您查看 DDMS,就会发现在输入与relativelayout 相关的文本时会发生大量重绘和重新计算。因此,这给了我们一个线索,问题确实是RelativeLayoutUpdate:我忘记提及设置 EditText 的固定值将对性能有很大帮助。它可以防止重新计算和重新绘制布局。\n 感谢 Giorgos Kylafas 在下面的评论\n 部分指出这一点!他还提供了在涉及 Android 性能技巧时对您有用的链接,因此我建议您阅读他的评论。
\n\n在第一种情况下,EditText 的宽度是“wrap_content”。每次更改文本(即 EditText 的内容)时,视图都需要重新测量并重新布局,这很慢。包含在RelativeLayout 中会使事情变得更糟,因为RelativeLayout 总是多通道的。
\n\n在第二种情况下,EditText 的宽度固定为“220 dial”。其测量和布局过程简单快捷。另外,您不使用\n“layout_weight”,因此其父 LinearLayout 是单通道的。\n http://developer.android.com/guide/topics/ui/how-android-draws.html
\n
来自另一个 stackoverflow问题:
\n\n\n\n\n避免在RelativeLayout中使用EditText,而使用LinearLayout\n。
\n
来自另一个 stackoverflow问题:
\n\n\n\n\n我在 ListView 中使用 EditText 时遇到了类似的问题,该问题已通过使用加权宽度将 EditText 宽度更改为 0dp 来匹配/填充父级来解决。
\n\n我不确定为什么会发生这种情况,但我相信这是因为当 EditText 的宽度设置为换行内容时,它会调整/重绘自身,以便一切都适合,并且 ListView 将\ n 还尝试重新绘制自身,以便一切都适合。因此,通过使 EditText 具有固定宽度,不再需要此重绘。
\n
结论:一定不要将EditText的宽度设置为wrap-content!
\n