【问题标题】:Delete object to free memory JAVA [duplicate]删除对象以释放内存JAVA [重复]
【发布时间】:2020-09-04 12:00:30
【问题描述】:

我正在开发一款小型太空射击游戏。这是学习 JAVA 的一种有趣方式,我想确保我做事正确。 该对象(船)在运行时生成其他对象(激光)。 (船 -> 激光)。

我是这样实现的:

  • 对象船被绘制在屏幕上。当检测到触摸时,它会创建 Laser 类的 实例,然后将它们添加到 GameScreen 类内的静态 LinkedList 激光中。
  • GameScreen 对象负责绘制和更新屏幕上的所有激光、船只和效果。

不言自明。但是现在:

  • detectCollision() 被调用,所有与船舶对象相交的激光都将从 LinkedList 激光中删除。
  • 在游戏结束时(用户退出),我遍历存储在 GameScreen.lasers 链表中的所有 Laser 类实例,并将它们全部设置为 null。 完成后我还将列表设置为 null。

这是释放分配内存的正确方法吗?

激光创作:

abstract class Ship {
if (canShoot()) {
    Laser laser = new Laser(new Rectangle(x, y, width, height)); // bounds
    GameScreen.playerLasers.add(laser);
}}

激光处理:

public class GameScreen {
private void dispose() {
    for (Laser laser : playerLasers) {
        laser.bounds = null;
        laser = null;
    }
    playerLasers = null;
}}

GameScreen 类碰撞检测():

public class GameScreen {
    private void detectCollision() {
        ListIterator<Laser> itr = playerLasers.listIterator();
        while (itr.hasNext()){
            Laser laser = itr.next();
            if (laser.bounds.overlaps(ship.bounds)){
                ship.health -= laser.damage;
                laser.bounds = null;
                laser = null;
                itr.remove();
}}}}

【问题讨论】:

  • 即使在 C 或 C++ 这样的编译语言中......当你的程序真正退出时(如你所说:用户退出),你不必释放任何内存。因为当该进程死亡时,操作系统会释放为特定进程分配的所有内存(除非我们可能会采用非常特定的东西,例如共享内存部分等)。换句话说:程序结束时没有清理。正如许多书籍和教程中所写的那样:在 java 中,当您不意外地创建内存泄漏时,GC 会为您完成所有释放操作,因此无需手动操作。
  • 并且注意:是的,一些古老的 Java 书籍建议将 null 分配给不再需要的东西,以明确告诉 gc“这可以消失”。但这在任何当今的 JVM 中都不是必需的。无论您在哪里“听说”做这些事情......最好获得更新/当前的信息来源。
  • 非常感谢。是的,我读过一些旧书:)
  • 在你的 dispose() 方法中,设置 laser = null 只是改变局部循环变量,对 playerLasers 列表没有任何作用。
  • 谢谢你我意识到了。这很有趣:D

标签: java memory linked-list dispose allocation


【解决方案1】:

不是。

Java 是一个垃圾收集系统。你不能“解除分配”。将东西设置为 null 不会使事情解除分配。

Java 会自动清理任何需要的内容,您无需执行任何操作即可实现。您唯一需要担心的是编程逻辑。例如,在这种情况下,您确实需要 itr.remove(); 调用 - 这不是关于释放激光对象,而是关于从游戏逻辑中删除激光射击。因此,删除 null alloc 行,最终得到:

if (laser.bounds.overlaps(ship.bounds)){
                ship.health -= laser.damage;
                itr.remove();
}

【讨论】:

  • 那为什么呢? link.
  • @J4Nk0 这是您不会遇到的极其复杂的东西,并且根本不适用于您的情况。他们正在向后弯曲以创建对象,以便活动代码仍然可以“获取它”。如果您从该迭代器中移除激光,您将无法再使用它,而 GC 会处理所有事情。
  • 感谢您的帮助!
猜你喜欢
  • 1970-01-01
  • 2019-04-21
  • 1970-01-01
  • 2016-11-27
  • 1970-01-01
  • 1970-01-01
  • 2011-02-14
  • 1970-01-01
  • 2017-05-13
相关资源
最近更新 更多