Android内存泄露(全自动篇)
写了可执行文件启动器Launcher.jar及一些批处理,通过它们就可以自动的以一定的时间间隔提取Hprof和进程的内存信息;
一、需要的库
可执行文件启动器:lib\Launcher.jar
注:关于Launcher.jar的源码如下:
源码包含2个文件Worker.java和Launcher.java
Worker.java文件:
源码文件2:Launcher.java
package com.teleca.robin;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
public class Launcher extends JFrame implements WindowListener{
private long interval;
private String executableFileName;
Launcher(String file,long time)
{
if(file==null)
executableFileName="";
else
executableFileName=file;
interval=time;
initComponents();
this.addWindowListener(this);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
/** This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
jButtonStart = new javax.swing.JButton();
jButtonPause = new javax.swing.JButton();
jButtonExit = new javax.swing.JButton();
jTextFieldFile = new javax.swing.JTextField(20);
jTextFieldTime = new javax.swing.JTextField(5);
jLabelFile = new javax.swing.JLabel();
jLabelTime = new javax.swing.JLabel();
jLabelTip = new javax.swing.JLabel();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setName("Form"); // NOI18N
jButtonStart.setText("Start"); // NOI18N
jButtonStart.setName("jButtonStart"); // NOI18N
jButtonStart.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
start();
}
});
jButtonPause.setText("Pause"); // NOI18N
jButtonPause.setName("jButtonPause"); // NOI18N
jButtonPause.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
pause();
}
});
jButtonExit.setText("Exit"); // NOI18N
jButtonExit.setName("jButtonExit"); // NOI18N
jButtonExit.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
stop();
System.exit(0);
}
});
jButtonStart.setEnabled(true);
jButtonPause.setEnabled(false);
jTextFieldFile.setText(executableFileName); // NOI18N
jTextFieldFile.setName("jTextFieldFile"); // NOI18N
jTextFieldFile.setHorizontalAlignment(JTextField.CENTER);
jTextFieldTime.setText(""+interval); // NOI18N
jTextFieldTime.setName("jTextFieldTime"); // NOI18N
jTextFieldTime.setHorizontalAlignment(JTextField.CENTER);
jLabelFile.setText("the executable file"); // NOI18N
jLabelFile.setName("jLabelFile"); // NOI18N
jLabelTime.setText("the interval time(millisecond)"); // NOI18N
jLabelTime.setName("jLabelTime"); // NOI18N
jLabelTip.setText("idle"); // NOI18N
jLabelTip.setName("jLabelTip"); // NOI18N
jLabelTip.setHorizontalAlignment(SwingConstants.CENTER);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(71, 71, 71)
.addComponent(jLabelTime))
.addGroup(layout.createSequentialGroup()
.addGap(70, 70, 70)
.addComponent(jLabelFile))
.addGroup(layout.createSequentialGroup()
.addGap(90, 90, 90)
.addComponent(jButtonStart)))
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(100, 100, 100)
.addComponent(jTextFieldTime, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGroup(layout.createSequentialGroup()
.addComponent(jTextFieldFile, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
)
.addGroup(layout.createSequentialGroup()
.addGap(10, 10, 10)
.addComponent(jButtonPause)
)
.addGroup(layout.createSequentialGroup()
.addGap(20, 20, 20)
.addComponent(jLabelTip)
)
.addGroup(layout.createSequentialGroup()
.addGap(180, 180, 180)
.addComponent(jButtonExit)
)
))
)
.addContainerGap(151, Short.MAX_VALUE))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(63, 63, 63)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jLabelFile)
.addComponent(jTextFieldFile, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGap(29, 29, 29)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jLabelTime)
.addComponent(jTextFieldTime, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGap(62, 62, 62)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jButtonStart)
.addComponent(jButtonPause)
.addComponent(jButtonExit))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 34, Short.MAX_VALUE)
.addComponent(jLabelTip)
.addGap(32, 32, 32))
);
pack();
}// </editor-fold>//GEN-END:initComponents
Worker worker;
private void stop() {//GEN-FIRST:event_stop
// TODO add your handling code here:
if(worker!=null)
{
worker.die();
worker=null;
}
}//GEN-LAST:event_stop
private void pause() {//GEN-FIRST:event_pause
// TODO add your handling code here:
worker.doPause();
jButtonStart.setEnabled(true);
jButtonPause.setEnabled(false);
jTextFieldFile.setEditable(true);
jTextFieldTime.setEditable(true);
}//GEN-LAST:event_pause
private void start() {//GEN-FIRST:event_start
// TODO add your handling code here:
String fileName=jTextFieldFile.getText().trim();
if(checkFileName(fileName))
{
executableFileName=fileName;
}
else
{
return;
}
String time=jTextFieldTime.getText();
if(time.length()==0)
{
interval=defaultInterval;
}
else
{
try{
long t=Long.parseLong(time);
interval=t;
}catch(NumberFormatException e)
{
jLabelTip.setText("the time "+time+"is not correct!");
return;
}
}
if(worker==null)
{
worker=new Worker(this.jLabelTip);
worker.setExecutableFileName(executableFileName);
worker.setInterval(interval);
worker.start();
jLabelTip.setText("start to execute file");
}
else
{
worker.setExecutableFileName(executableFileName);
worker.setInterval(interval);
worker.doResume();
jLabelTip.setText("Restart to execute file");
}
jButtonStart.setEnabled(false);
jButtonPause.setEnabled(true);
jTextFieldFile.setEditable(false);
jTextFieldTime.setEditable(false);
}//GEN-LAST:event_start
final static long defaultInterval=1000;
/**
* @param args
*/
public static void main(String[] args) {
String fileName="";
long time=defaultInterval;
if(args.length>0)
{
fileName=args[0];
if(!checkFileName(fileName))
{
fileName="";
}
}
if(args.length>1)
{
time=Long.parseLong(args[1]);
}
// TODO Auto-generated method stub
new Launcher(fileName,time).setVisible(true);
}
static boolean checkFileName(String fileName)
{
if(fileName==null)
{
return false;
}
if(!(fileName.endsWith(".exe")||fileName.endsWith(".bat")||fileName.endsWith(".cmd")))
{
System.out.println("the file must be a executable file!");
System.out.println("Now only support *.exe , *.bat,*.cmd");
System.out.println("Please check the file again");
return false;
}
File file=new File(fileName);
if(!file.exists())
{
System.out.println("the file:"+fileName+" is not exists");
return false;
}
return true;
}
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton jButtonExit;
private javax.swing.JButton jButtonPause;
private javax.swing.JButton jButtonStart;
private javax.swing.JLabel jLabelFile;
private javax.swing.JLabel jLabelTime;
private javax.swing.JLabel jLabelTip;
private javax.swing.JTextField jTextFieldFile;
private javax.swing.JTextField jTextFieldTime;
// End of variables declaration//GEN-END:variables
public void windowDeactivated(WindowEvent e)
{
//System.out.println("window is deactivated");
}
public void windowDeiconified(WindowEvent e)
{
//System.out.println("window is Deiconified");
}
public void windowActivated(WindowEvent e)
{
//System.out.println("window is actived");
}
public void windowOpened(WindowEvent e)
{
//System.out.println("window is Opened");
}
public void windowClosing(WindowEvent e)
{
stop();
}
public void windowClosed(WindowEvent e)
{
//System.out.println("window is Closed");
}
public void windowIconified(WindowEvent e)
{
//System.out.println("window is Closing");
}
}
用源代码生成的jar文件为:Launcher.jar。
则可以用如下的DOS命令运行它:
使用实例1:
表示2000毫秒执行一次 getMemoryState.bat来从手机提取进程的内存信息到一个以进程名命名的文本文件,以便在excel中生产图表文件。
本文来自:http://hubingforever.blog.163.com/blog/static/1710405792011324114317115/
Android内存泄露(全自动篇)的更多相关文章
- (转)专项:Android 内存泄露实践分析
今天看到一篇关于Android 内存泄露实践分析的文章,感觉不错,讲的还算详细,mark到这里. 原文发表于:Testerhome: 作者:ycwdaaaa ; 原文链接:https://teste ...
- Android内存泄露---检测工具篇
内存使用是程序开发无法回避的一个问题.如果我们毫不在意肆意使用,总有一天会为此还账,且痛不欲生...所以应当防患于未然,把内存使用细化到平时的每一行代码中. 内存使用概念较大,本篇先讲对已有app如何 ...
- 【android内存泄露】 WebView篇
在咱的博客园app里,新闻的内容使用WebView展示的.在测试中,咱重复进入.退出某个新闻10多次,观察到 Objects一直在不断增长,反复触发GC,但是一直回收不了,占用的内存越来越高,于是警觉 ...
- JVM内存管理概述与android内存泄露分析
一.内存划分 将内存划分为六大部分,分别是PC寄存器.JAVA虚拟机栈.JAVA堆.方法区.运行时常量池以及本地方法栈. 1.PC寄存器(线程独有):全称是程序计数寄存器,它记载着每一个线程当前运行的 ...
- Android 内存泄露总结(附内存检测工具)
https://segmentfault.com/a/1190000006852540 主要是分三块: 静态储存区:编译时就分配好,在程序整个运行期间都存在.它主要存放静态数据和常量. 栈区:当方法执 ...
- Android内存泄露
Android 内存泄漏是一个十分头疼的事情.LeakCanary是一款开源软件,主要作用是检测 Android APP 内存泄露.比起以前的 MAT 工具,LeakCanary 有着十分强大的功能, ...
- android内存泄露调试,Heap,MAT
三.内存监测工具 DDMS --> Heap 无论怎么小心,想完全避免bad code是不可能的,此时就需要一些工具来帮助我们检查代码中是否存在会造成内存泄漏的地方.Android tools中 ...
- Android内存泄露测试
Android性能测试过程中的一些常用命令: CPU: adb shell top -n | grep "+PackageName 内存: adb shell dumpsys meminfo ...
- android内存泄露小谈
在做android的时候,用的语言大部分情况下都是java.以前最开始做的是编译器开发, 大部分情况都是用c语言和x86与arm架构的汇编,后来接触到ios用的是OC.对比之下, 感觉还是java用起 ...
- android 内存泄露之jni local reference table overflow (max=512)
在android项目中要实现一个需求 为了性能的要求只能用c代码来实现功能. 这样就牺牲了java跨平台性. 通过加载.so的方式,把用c实现的模块集成到app中. android提供jni层,作为一 ...
随机推荐
- oracle:rman恢复----通过时间set until time
试验计划:先做一个0级备份,再创建一个表,插入几条数据,最后删除表,然后通过rman把该表的数据恢复. 试验环境:在归档模式,oracle10.2.0.1 开始试验: 1.rman level 0备份 ...
- 让振动器振动起来——Vibrator的使用
AndroidManifest.xml 获取系统权限 <uses-permission android:name="android.permission.VIBRATE"/& ...
- 两种 NIO 实现:Selector 与 Epoll
[总结]两种 NIO 实现:Selector 与 Epoll 时间2012-11-17 08:38:42 开源中国新闻原文 http://my.oschina.net/ielts0909/blog/ ...
- 2018.8.10Yukimai模拟Day1
这的确是最惨的一次模拟了……不会再惨了(10pts除非爆零orz) 总结一下吧…… T1 .章鱼 众所周知,雪舞喵有许多猫.由于最近的天气十分炎热,雪舞城的大魔法师雪月月根本不想出门,只想宅在家里打隔 ...
- 行内元素变成会计元素block和inline-block的区别
左边一个ul的导航,习惯了用li里面放a,想要a有个百分百宽和高,这个整个li就都可以有点击事件了,用了inline-block,宽高可以实现,但是发现一个问题,a的左边始终会有个类似于外边距的样式, ...
- 你真的懂redis吗?
Redis在互联网技术存储方面使用如此广泛,几乎所有的后端技术面试官都要在Redis的使用和原理方面对小伙伴们进行各种刁难.作为一名在互联网技术行业打击过成百上千名[请允许我夸张一下]的资深技术面试官 ...
- 洛谷P3830 [SHOI2012]随机树——概率期望
题目:https://www.luogu.org/problemnew/show/P3830 询问1:f[x]表示有x个叶节点的树的叶节点平均深度: 可以把被扩展的点的深度看做 f[x-1] ,于是两 ...
- word-break: break-all word-break:keep-all word-wrap: break-word三者的区别
word-break属性:指定非CJK脚本的断行规则. 值 描述 normal 使用浏览器默认的换行规则. break-all 允许在单词内换行. keep-all 只能在半角空格或连字符处换行. w ...
- 在idea中创建maven父子工程,子工程无法导入父工程依赖的问题
创建maven父子工程时遇到一个问题,当子工程的名称前缀和父工程的名称一样时,子工程会出现一系列的问题.比如我的父工程名称是microservicecloud,子工程名称是microservicecl ...
- UVaLive 6581 && Gym 100299B What does the fox say? (模拟+STL)
题意:给定一些动物的叫声,然后再定某些动物的叫声,让你去除这些叫声后得到的叫声. 析:先存储所有的叫声,然后用map来记录其他的叫声,在输出时再判定一下就好. 代码如下: #pragma commen ...