【发布时间】:2021-08-09 11:25:07
【问题描述】:
我一直在尝试学习垃圾收集器,以制作对内存更友好的 Java 应用程序。 我有一个关于垃圾收集器的问题,假设我们有这样的功能:
public void personWork(){
List<Person> firstPersonList = personService.getFirstPersonList();
List<Person> secondPersonList = personService.getSecondPersonList();
// Do something with firstPersonList
..
..
..
// Do something with secondPersonList
..
..
..
finish the function
}
我也可以用这段代码做同样的事情
public void personWork(){
List<Person> firstPersonList = personService.getFirstPersonList();
List<Person> secondPersonList = personService.getSecondPersonList();
firstPersonListJob(firstPersonList);
secondPersonListJob(secondPersonList);
//finish the function
}
public void firstPersonListJob(List<Person> firstPersonList){
// do someting with firstPersonList
}
public void secondPersonListJob(List<Person> secondPersonList){
// do something with secondPersonList
}
终于我也能做到了:
public void personWork(){
firstPersonListJob();
secondPersonListJob();
//finish the function
}
public void firstPersonListJob(){
List<Person> firstPersonList = personService.getFirstPersonList();
// do someting with firstPersonList
}
public void secondPersonListJob(){
List<Person> secondPersonList = personService.getSecondPersonList();
// do something with secondPersonList
}
据我从垃圾收集器中了解到,为了垃圾收集器清理堆,必须从堆栈中删除堆内存中值的引用。考虑到第一种和第二种方法不利于内存管理,因为 2 List 一直存在到完成,但在最后一种方法中,当函数 1 完成时,firstPersonList 也会被删除。
实际上我不确定哪种方法更适合内存管理,或者我是否关心这种事情?
【问题讨论】:
-
我看不出有什么理由去在意用这些方法取悦 GC。无论如何,一旦它们超出范围,GC 就不会收集您的陈旧引用。运行 GC 本身就是一项昂贵的任务,因此它只会在最佳时间运行是有道理的。
-
在您的第一个示例中,您早在需要之前就实现了
secondPersonList,即在处理firstPersonList时不需要它。因此,最后一个 sn-p 避免了两个列表同时在内存中,您也可以通过重新排序代码来使用早期的变体来实现这一点。但是您可能会注意到,最后一种方法如何自动导致更好的设计。所以使用更小的函数,不管垃圾回收。另请阅读Separation of concerns。