KeyboardPianoV1.7.1 Debug(贴图优化)

本文详细解析了在V1.5.1版本中,MyButton类的switchCase&graphicsImageSet()方法导致的内存泄漏问题。通过代码分析,指出每次paint都会重复初始化按钮贴图,造成不必要的内存消耗。提出了在MyButton实例化时仅初始化一次贴图的解决方案,显著降低了内存占用,从优化前的290+M减少到120+M。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


详细步骤

例行说明

  • Debug 开篇引言——越往后越难,情况越多越复杂,坐稳啦

  • V1.5.1switchCase & graphicsImageSet() 的代码解释下有引出一个 BUG

每 paint 一次,就会初始化一次按钮的贴图,重复的初始化,导致无缘无故地消耗内存,属于代码逻辑错误

具体步骤

  • 正确的处理方式,new 一个 MyButton贴图初始化一次即可paint 的时候把图贴上去就行,这样就可以避免重复初始化导致过多的内存消耗
  • 优化过程排除干扰项的说明请见 Option

代码分析

  • MyButton 初始化
    1. setImageAndWavByName() 初始化按钮路径
      1. modifyImageByType() 根据按钮类型对按钮进行修改
        1. setImageByType() 设置图片与按钮大小相适应

注:这里一些方法只是重命名而已,方法体内代码做了调整,并没有过多修改

就如之前所说,这里只贴核心代码,详细请见 V1.7.1 MyButton

MyButton(KeyboardPiano kp, String text, String name) {
    setImageAndWavByName(name);
}

public void setImageAndWavByName(String name) { //UpName
	modifyImageByType(imageName.charAt(TYPE_INDEX));
}

private void modifyImageByType(int type) { //char type actually
	switch(type) {
	case A :
		setImageByType(A_TYPE, 2, 2);
		break;
	}
}

private void setImageByType(int type, int widthMinus, int heightMinus) {
	imageUp.setImage(imageUp.getImage().getScaledInstance(type-widthMinus, HEIGHT-heightMinus, Image.SCALE_DEFAULT));
	imageDown.setImage(imageDown.getImage().getScaledInstance(type-widthMinus, HEIGHT-heightMinus, Image.SCALE_DEFAULT));
}

其实这些代码可以写在一个方法体内,但这样代码太臃肿,这也是为什么要用多个方法体来做一件事的原因
同时博主对方法重命名,其实意在体现命名规范的重要性——见名知意!!(前面的命名方式实在不堪入目(●′ω`●))

  • paintComponent() 画组件
    1. fillRectByType() 根据类型处理按钮圆角
protected void paintComponent(Graphics g) {
    fillRectByType(g2d, imageName.charAt(TYPE_INDEX));
}

private void fillRectByType(Graphics2D g2d, int type) { //char actually
	switch(type) {
	case A :
		g2d.fillRoundRect(0, 0, A_TYPE, HEIGHT, ARC_WIDTH, ARC_HEIGHT); //make Rectangle more beautiful
		break;
	}
}

细心的童鞋会发现,其实 fillRectByType 就是从 setImageByType 分离出来的,这样初始化 & 重画的工作分开,也就减少了内存的压力

  • 最后贴几张图看一下优化的效果(读者也可自行比较验证)

  • img1 程序初始化所占内存 80+ M
    img1

  • img2 V1.7 1000+ 次按键后,内存占用 290+ M
    img2

  • img3 V1.7.1 贴图优化后,1000+ 次按键后,内存占用 120+ M
    img3

由此可见,内存上做了很大的优化,但并未做到 0 泄露,有待进一步的优化


Option

  • 控制变量法——单一变量原则
    测试过程去除音频干扰,避免多变量影响内存而混淆视听,这个是 Debug/Test 过程常用的方法

  • 做法很简单,直接把 MusicPlayer 注释即可

@Override
protected void paintComponent(Graphics g) {
    
	if(this.isSelected()) {
		g2d.drawImage(imageDown.getImage(), 1, 1, null);
		/*
		 * play music once
		 */
//		new Thread(new MusicPlayer(getType(), wavPath)).start();
	} else { //default is Up
		g2d.drawImage(imageUp.getImage(), 1, 1, null);
	}
	
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值