尽量减少对变量的重复计算
明确一个概念,对方法的调用,即使方法中只有一句语句,也是有消耗的,包括创建栈帧、调用方法时保护现场、调用方法完毕时恢复现场等。所以例如下面的操作:
for (int i = 0; i < list.size(); i++) {
...
}
建议替换为:
for (int i = 0, int length = list.size(); i < length; i++) { ... }
这样,在list.size()很大的时候,就减少了很多的消耗
尽量采用懒加载的策略,即在需要的时候才创建
例如:
String s = "a"; if (i == 1) { list.add(s); }
建议替换为:
if (i == 1){ String s = "a"; list.add(s); }
当复制大量数据时,使用System.arraycopy()命令
当复制大量数据时,使用System.arraycopy()
命令比其他方法更快的原因主要有以下几点:
-
底层优化:
System.arraycopy()
方法是由底层的本地代码实现的,通常是由Java虚拟机(JVM)的实现者进行高度优化的。这些实现可以利用底层平台的特性和优化技术,比如使用底层内存拷贝操作来提高效率。扫描二维码关注公众号,回复: 17404467 查看本文章 -
避免额外的方法调用开销:
System.arraycopy()
方法是一个原生的Java方法,避免了额外的方法调用开销。相比之下,使用循环或者其他手动复制方法可能会涉及到更多的方法调用,增加了额外的开销。 -
内存连续性:
System.arraycopy()
方法可以利用内存的连续性来提高复制效率。由于底层实现是针对连续内存进行优化的,因此在复制大量数据时能够更有效地利用CPU缓存等硬件资源,减少了访问非连续内存的开销。
乘法和除法使用移位操作
例如:
for (val = 0; val < 100000; val += 5){ a = val * 8; b = val / 2; }
用移位操作可以极大地提高性能,因为在计算机底层,对位的操作是最方便、最快的,因此建议修改为:
for (val = 0; val < 100000; val += 5){ a = val << 3; b = val >> 1; }
移位操作虽然快,但是可能会使代码不太好理解,因此最好加上相应的注释。
循环内不要不断创建对象引用
public class ObjectCreationExample {
public static void main(String[] args) {
// 示例 1: 在循环内部创建对象引用
for (int i = 0; i < 1000; i++) {
String str = new String("Object " + i); // 在循环内部创建字符串对象引用
System.out.println(str);
}
// 示例 2: 在循环外部创建对象引用
String str; // 在循环外部声明字符串对象引用
for (int i = 0; i < 1000; i++) {
str = new String("Object " + i); // 在循环内部为之前声明的引用赋值
System.out.println(str);
}
}
}
在示例1中,我们在循环内部创建了String
对象的引用。每次循环迭代时,都会创建一个新的String
对象,并且在循环结束后,这些对象会成为垃圾对象,增加了垃圾回收的压力。
而在示例2中,我们在循环外部创建了String
对象的引用,并在循环内部重复使用这个引用。这样做可以避免在每次循环迭代时都创建新的对象引用,减少了内存开销和垃圾回收压力,提高了程序的性能。
尽量避免随意使用静态变量
当某个对象被定义为静态变量引用时,即使程序不再需要该对象,Java 的垃圾收集器(Garbage Collector,GC)通常也不会回收该对象所占用的堆内存。这是因为静态变量的生命周期通常会与应用程序的生命周期保持一致,除非显式地将静态变量设为 null 或程序结束,否则静态变量所引用的对象不会被释放。
public class StaticVariableLeakExample {
// 定义一个静态变量引用
private static MyClass staticReference;
public static void main(String[] args) {
// 创建一个对象,并将其赋值给静态变量引用
staticReference = new MyClass();
// 执行某些操作,但是没有将静态变量置为 null
// 这意味着即使在这个对象不再被使用时,它所占用的内存也不会被释放
// MyClass对象实际上无法被垃圾收集器回收,因为它仍然被静态变量staticReference引用着
// 在应用程序的其他地方仍然可以通过staticReference引用访问MyClass对象
}
}
class MyClass {
// 一些成员变量和方法
}
静态变量 staticReference
引用了一个 MyClass
的实例。即使在 main
方法结束后,staticReference
仍然保持对这个对象的引用。这意味着即使 main
方法中的对象不再被使用,它所占用的内存也不会被释放。如果这种情况发生在一个长时间运行的应用程序中,可能会导致内存泄漏问题,逐渐消耗系统的内存资源。因此,在使用静态变量时,需要注意在不再需要对象时及时将其置为 null,以避免内存泄漏的发生。
字符串变量和字符串常量equals的时候将字符串常量写在前面
这是一个比较常见的小技巧了,如果有以下代码:
String str = "123"; if (str.equals("123")) {...}
建议修改为:
String str = "123"; if ("123".equals(str)) {...}
这么做主要是可以避免空指针异常
公用的集合类中不使用的数据一定要及时remove掉
-
内存管理:未使用的数据如果一直保留在集合中,会占用额外的内存空间。特别是在大规模数据处理或者长时间运行的应用中,未使用的数据可能会导致内存占用不断增加,最终导致内存溢出或性能下降。
-
避免内存泄漏:如果未使用的数据一直保留在集合中,而且这些数据引用了其他对象,那么这些对象也会一直存在于内存中,即使它们本身已经不再被需要。这可能会导致内存泄漏,即一些对象永远无法被垃圾收集器回收。
-
提高性能:集合类的操作可能会涉及到遍历、查找和删除等操作,如果集合中包含大量未使用的数据,这些操作的性能可能会受到影响。及时移除未使用的数据可以减少集合的大小,提高操作的效率。