首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java内存泄漏-静态与Beans

Java内存泄漏-静态与Beans
EN

Stack Overflow用户
提问于 2022-01-27 09:19:56
回答 1查看 361关注 0票数 1

因此,我仍然在学习内存管理的一般知识,而不仅仅是Java。我在这个白龙文章上读过。

本文展示了以下代码的示例:

代码语言:javascript
复制
public class StaticTest {
    public static List<Double> list = new ArrayList<>();

    public void populateList() {
        for (int i = 0; i < 10000000; i++) {
            list.add(Math.random());
        }
        Log.info("Debug Point 2");
    }

    public static void main(String[] args) {
        Log.info("Debug Point 1");
        new StaticTest().populateList();
        Log.info("Debug Point 3");
    }
}

我在示例中了解到,如果list是静态的,Java仍然保留对象,而不是垃圾收集对象。但是,如果删除static关键字,那么在离开populateList方法之后,它将被垃圾收集。

但如果场景是豆子的话。考虑一下Spring项目中的这个示例:

代码语言:javascript
复制
@RestController
public class UserController {
    @Autowired
    private UserService userService;

    private List<User> userList = new ArrayList<>();

    @GetMapping("/users")
    public ResponseEntity<List<User>> getAllUser() {
        List<User> userList = userService.findAll();

        for(User u: userList) {
            this.userList.add(u);
        }

        return ResponseEntity.ok(userList);
    }
}

在使用@RestController进行注释时,将创建一个bean,但在我自己的测试中,这不会导致内存泄漏,或者,即使对象计数相同,堆内存至少也不会像static list那么大。根据我对Bean的理解,userList应该仍然在内存中,不应该被垃圾收集,那么有什么区别呢?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-01-27 09:30:52

你从错误的角度看它。最后,决定垃圾收集器是否收集对象的不是静态的,也不是作为bean的。

唯一的条件是:该对象是否仍然被认为是活动的?!

当可以从正在运行的线程的上下文“到达”对象时,这些对象被认为是活动的。

换句话说:静态成员由相应的类对象引用。而加载类的ClassLoader则(很可能)引用了这些类。因此,静态成员通常是活着的,不会被收集。

对于bean示例,重点是:这是一个在外部REST请求传入时将被调用的方法。接下来:处理请求,准备响应数据,将响应数据与答案一起发送出去。

现在:响应对象引用了bean对象。但是,在答复发出后,再也没有提到答复。因此,没有对bean的引用。因此,list对象不再是活动的,list、bean、response都是垃圾收集的对象。

但是:是的,UserController实例不断向字段添加用户对象。因此,存在一个用于内存泄漏的潜在

如果Spring框架丢弃了,那么这些UserContext对象:没有内存泄漏。如果它一次又一次地使用同一个对象,那么这个列表就会增加,并导致内存泄漏。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70876040

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档