Java代码优化咨询:堆内存受限下解决内存异常的方案
Java代码内存优化方案
针对这段代码运行时出现的内存异常问题,以下是几个可行的优化方向:
复用重复创建的对象
原代码每次循环都新建SimpleDateFormat实例,还重复解析同一个日期字符串,会产生大量冗余对象。可以提前解析好日期,循环里直接复用:// Java 8+推荐用DateTimeFormatter(线程安全)提前初始化 private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("ddMMyyyy"); private static final LocalDate BIRTH_DATE = LocalDate.parse("01061986", DATE_FORMATTER);若使用Java 8以下版本,注意
SimpleDateFormat线程不安全,单场景提前初始化即可,多线程环境需加锁或用ThreadLocal处理。砍掉不必要的对象创建
- 别用
new Integer(i),直接写i就行,Java会自动装箱,还能利用Integer的缓存机制减少对象实例。 - 字符串拼接里的
new String((new Integer(i)).toString())完全多余,直接写"Customer" + i,编译器会自动优化成高效的拼接方式,无需手动创建多余对象。
- 别用
给ArrayList指定初始容量
原代码中ArrayList默认初始容量为10,存满后会扩容并复制数组,既耗内存又耗时。直接把初始容量设为100000,避免多次扩容操作:List<Customer> customers = new ArrayList<>(100000);按需加载(应对超大数据量)
如果10万条数据仍超出内存限制,别一次性把所有Customer塞进List,改用懒加载方式,用到对象时再创建。比如用迭代器实现:public static Iterable<Customer> retrieve() { return () -> new Iterator<>() { private int i = 0; @Override public boolean hasNext() { return i < 100000; } @Override public Customer next() { if (!hasNext()) throw new NoSuchElementException(); Customer customer = new Customer(); customer.setAge(i); customer.setBirthDate(BIRTH_DATE); customer.setName("Customer" + i); i++; return customer; } }; }这样遍历过程中才会创建对象,不会一次性占满堆内存。
优化Customer类(如果可修改)
若Customer类允许调整,把Integer age改成int age,用基本类型避免装箱对象的内存开销;另外因为所有客户的出生日期都相同,甚至可以在Customer里把出生日期设为静态常量,不用每个对象都存储一份。
优化后的完整代码示例(Java 8+)
import java.time.LocalDate; import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.List; public class GetCustomerList { private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("ddMMyyyy"); private static final LocalDate BIRTH_DATE = LocalDate.parse("01061986", DATE_FORMATTER); public static List<Customer> retrieve() { List<Customer> customers = new ArrayList<>(100000); for (int i = 0; i < 100000; i++) { Customer customer = new Customer(); customer.setAge(i); customer.setBirthDate(BIRTH_DATE); customer.setName("Customer" + i); customers.add(customer); } return customers; } static class Customer { private int age; // 改用基本类型 private LocalDate birthDate; private String name; public void setAge(int age) { this.age = age; } public void setBirthDate(LocalDate birthDate) { this.birthDate = birthDate; } public void setName(String name) { this.name = name; } } }
内容的提问来源于stack exchange,提问作者Nick B
相关产品推荐
相关产品推荐

