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:varchar2、nvarchar2 字段类型的区别
一直对varchar2.nvarchar2 字段类型存储字符数不清楚,现测试如下: 创建TT测试表 测试脚本如下: insert into tt values('1111','1111'); --- ...
- WCF寄宿到Windows Service[1]
WCF寄宿到Windows Service 返回 在前面创建一个简单的WCF程序,我们把WCF的服务寄宿到了Host这个控制台项目中了.下面将介绍如何把WCF的服务寄宿到Windows服务中(源代码) ...
- How to run Media SDK samples on Skylake【转载】
In the last few days, we have seen lot of concern for using Intel® Media 2016 on 6th generation Inte ...
- Snowflake算法 ID生成
Snowflake算法 ID生成 http://blog.csdn.net/w200221626/article/details/52064976 使用UUID或者GUID产生的ID没有规则 Snow ...
- iOS 堆和栈的区别和联系
堆和栈的区别主要有以下五点: 1.管理方式:对于栈来讲,是由编译器自动管理,无需我们手工控制:对于堆来讲,释放工作由程序员控制,容易产生memory leak(内存泄露). 2.申请大小: 栈是向低地 ...
- View Controller Programming Guide for iOS---(六)---Responding to Display-Related Notifications
Responding to Display-Related Notifications 响应跟显示相关的通知 When the visibility of a view controller’s vi ...
- 当打开一个.h或.cpp文件时, Solution Explorer就自动展开文件所在的目录
当打开一个.h或.cpp文件时, Solution Explorer就自动展开文件所在的目录: 如果不想展开: Tools -> Options -&g ...
- python property的2种使用方法
一.property类 class Person(): def __init__(self, name): self.set_name(name) def get_name(self): return ...
- Photoshop下载
Adobe Photoshop,简称“PS”,是由Adobe Systems开发和发行的图像处理软件.Photoshop主要处理以像素所构成的数字图像.使用其众多的编修与绘图工具,可以有效地进行图片编 ...
- 左耳朵耗子:我为什么要在极客时间 App 开设独家专栏?
参考链接:https://www.infoq.cn/article/2018/01/why-geektime 不少朋友都知道我在极客时间App 上开了一个收费专栏<左耳听风>,这个专栏会开 ...