JAVA---优化编程读书笔记(一)

本文介绍了JAVA编程中的优化技巧,包括JVM内存管理、代码规范、类与接口的设计原则等内容,帮助开发者提高程序性能。

JAVA优化编程读书笔记

一、基本的代码规范 我就不记了

二、JVM内存管理

垃圾回收GC:

垃圾:对象在JVM运行空间中无法通过根集合到达时。根集合是由类中的静态引用域和本地引用域组成的。

堆、栈、代码区、数据段

新对象区域与老对象区域。

 

JVM中对象的生命周期

Creation---Using---Invisible---Unreachable---Collected---Finalized---Free

创建对象时:

1.      避免在循环体中创建对象

2.      及时使对象符合垃圾回收准则,引用置空

3.      不要采用过深的继承层次

4.      访问本地变量优于访问类中的变量

5.      不要对一个对象多次初始化,尽量在使用时再初始化

 

Strong---Soft---Weak---Phantom Reference

 

在出了作用范围后,及时把对象的引用置为null。

最后一个阶段:

1.      GC发现对象不可达

2.      Finialize已经被执行

3.      对象空间被重用

 

 

 

Finalize

可以单独写一个destroy,在finalize中调用,并且在子类中重写这两个方法以实现递归释放

 

数组创建

可以用软引用来引用数组,提醒JVM及时回收

 

静态变量

1、  变量包含的对象体积大

2、  变量所包含对象生命周期较长

3、  对象数据稳定

4、  该类的对象实例共享该变量

 

对象重用与GC

连接池要注意:

及时清除不用的对象,注意内存限制

 

瞬间值

在RMI时对于不需要传输的数据加上transient修饰,防止被序列化。

 

不要提前创建对象

JVM内存参数调优

可以更改堆栈的大小,类文件的大小

 

 

三、表达式、语句与保留字

简单,单一意图。

== 比 equals更有效,在比较对象的引用是否相等时可采用==

字符串intern驻留后更方便的使用==来进行比较

 

常用保留字:

Static:

在非静态方法中不能引用静态变量

Final:

防止方法被子类覆盖。

内联函数:

把代码插入到调用者代码处的函数,宏是由预处理器对宏进行替代,内联函数是由编译器控制的,在需要用到时像宏一样展开,取消了参数压栈,减小了调用开销,但是代码不能太多。

Final的方法的代码展开后插入到调用者代码处,提高效率。

 

Synchronized: 只能被一个线程访问。

Instanceof: null不是任何对象的引用


For:循环中使用int类型作为步进比较好,short/byte会被隐式转化为int。

1.      尽量使用system.arraycopy来拷贝数组

2.      尽量避免在循环中调用方法。

3.      避免在循环中存取数组元素,最好在循环体内使用临时变量,在循环体外更改数组的值

4.      尽量采用0作为循环的终结条件,即i—

5.      避免在最终条件的比较时采用方法返回值来判断,可以单独写一个Boolean再比较

6.      在循环体外使用try/catch

7.      把最长的循环放在内层,最短的放在外层,减少循环切换

8.      循环体内有逻辑判断时,尽量放在循环外

 

 

四、JAVA核心类与性能优化

1. 散列表类: Vector、HashTable线程安全的,ArrayList、HashMap非线程安全的,但是效率更高。尽量使用ArrayList,可以通过 List list = Collections.synchronizedList(newArrayList());使其线程安全。

2. 在已知容量时,ensureCapacity()更好

3. Array与Linked选择根据需要来。

 

4.      字符串String:尽量使用StringBuffer和append

5.      尽量避免在循环中调用string.length(),因为调用方法是需要代价的,与array.length不同,这个只是一个属性,只会初始化一次

6.      toCharArray代替charAt()去访问特定下标的元素,因为索引更加高效

7.      字符串转换为数字不如直接把数字转换为数字高效。

 

8.      最好使用Buffered来缓冲输入输出流,自定义的缓冲区最好是512的倍数。

9.      通过压缩流来减少网络上传输负载

10.  通过非阻塞流NIO

11.  最好使用操作符如+等来格式化数据,生成一致格式的字符串

12.  File长度的length()方法需要OS的系统调用来完成,尽量避免重复使用。

 

 

五、JNI

六、类与接口

1、 不要再构造器中初始化其他类

2、 不用再构造器中初始化静态变量,只需要初始化一次即可

3、 不能再构造器中创建自身实例,会造成死循环

4、 类名一般用public修饰,除非是内部类或者不想被包以外的访问

5、 内部类只能被主类以外的其他内部类继承,但是也尽量避免使用

6、 分清楚何时该使用继承或者组合

7、 接口与抽象类:

相同:1. 接口和抽象类均不能被实例化

     2. 接口和抽象类中都可以有属性

不同:1. 接口的属性是public static final,方法是public abstract的

     2. 接口的方法不能有方法体,抽象类可以,甚至可以有非抽象方法

     3. 接口可以多重继承,抽象类单重

     4. 接口不能作为主应用程序独立运行,抽象类在特定的声明下可以,如static方法在main中被调用


public abstract class GCTeat{
	private static void show()
	{
		System.out.println("hello, i am abstract class");
	}
	
	public static void main(String[] args)
	{
		show();
	}
}

 


在接口中尽量少定义常量,避免名称空间混乱;抽象类的效率更高一点,两个一般都采用工厂方法模式实现。

 

8、 内部类:可以访问主类所有成员,但是主类不能直接访问内部类,需要创建实例来引用

内部类中不能声明static成员。常见用法:在类中创建一个线程类,调用主类的返回周期较长的方法。

 

import java.lang.*;
public class InnerClass
{
	private boolean flag = true; 
	public InnerClass()
	{
		new Thread(new innerThread()).start();
	}
	
	private void mainMethod()
	{
		while(flag)
		{
			System.out.println("hello!");
			//forbidden: System.out.println(index);
			try
			{
				
				Thread.sleep(3000);
			}
			catch(Exception e)
			{
			}
		}
	}
	public class innerThread implements java.lang.Runnable{
		//forbidden: private static int index = 1;
		public int index = 1;
		public void run()
		{
			mainMethod();
		}
	}
	
	public static void main(String [] args)
	{
		InnerClass ic = new InnerClass(); 
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Anyanyamy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值