Java优化 - 领域对象

Java优化 - 领域对象

Domain objects表达程序里的业务概念。比如电子商务系统里的Order、OrderItem和DeliverySchedule。这些类型之间有相关关系(Order可以包含多个OrderItem实例)。例如:

public class Order {
    private final long id;
    private final List<OrderItem> items = new ArrayList<>();
    private DeliverySchedule schedule;

    public Order(long id) {
        this.id = id;
    }

    public DeliverySchedule getSchedule() {
        return schedule;
    }

    public void setSchedule(DeliverySchedule schedule) {
        this.schedule = schedule;
    }

    public List<OrderItem> getItems() {
        return items;
    }

    public long getId() {
        return id;
    }
}

public class OrderItem {
    private final long id;
    private final String description;
    private final double price;

    public OrderItem(long id, String description, double price) {
        this.id = id;
        this.description = description;
        this.price = price;
    }

    @Override
    public String toString() {
        return "OrderItem{" + "id=" + id + ", description=" +
                description + ", price=" + price + '}';
    }
}

public class DeliverySchedule {
    private final LocalDate deliveryDate;
    private final String address;
    private final double deliveryCost;

    private DeliverySchedule(LocalDate deliveryDate, String address,
                             double deliveryCost) {
        this.deliveryDate = deliveryDate;
        this.address = address;
        this.deliveryCost = deliveryCost;
    }

    public static DeliverySchedule of(LocalDate deliveryDate, String address,
                                      double deliveryCost) {
        return new DeliverySchedule(deliveryDate, address, deliveryCost);
    }

    @Override
    public String toString() {
        return "DeliverySchedule{" + "deliveryDate=" + deliveryDate +
                ", address=" + address + ", deliveryCost=" + deliveryCost + '}';
    }
}

可以看到,领域类型之间有所有权关系,见下图。当然,领域对象图的叶子节点,大部分是简单的数据类型,比如字符串、原始类型和LocalDateTime。
Domain objects graph

使用jmap -histo命令,可以查看堆内状态,当然,也可以使用GUI工具,比如VisualVM。学习这些工具,可以诊断领域对象的内存泄漏情况。
另一个常见的领域对象泄漏行为是“所有代”效应-特定类型的对象没有被回收。这意味着他们会存活足够长时间成为Tenured,经过足够多的survive回收之后,有很大的代计数(generational count)。
如果我们绘制每个代计数的每个数据类型的字节数量的直方图,可以看到泄漏的领域对象跨越所有的代。应该查看领域对象相关的数据集的大小,看这些值是否合理。
而短期存活的领域对象能导致浮动垃圾问题。回想一下并发回收的SATB约束-如果在标记周期开始后分配的对象,无论有多短命,也被认为是活的。领域对象泄漏能导致高的GC标记时间,根本原因是单个长期存活的对象会让整个对象链长期存活。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值