当看似无关的代码块被注释掉时,出现OutOfMemoryError

当看似无关的代码块被注释掉时,出现OutOfMemoryError,第1张

当看似无关的代码块被注释掉时,出现OutOfMemoryError

我研究了许多不同类型的代码片段,可以将它们插入您的注释所在的位置,并且唯一不会导致的

OutOfMemoryError
代码类型是将一些值分配给局部变量的代码。

这是对我来说最有意义的解释:

当你有

byte[] data = new byte[dataSize];

字节码指令是

    12: newarray       byte    14: astore_1

在哪里

newarray
创建一个新数组并将
astore_1
对它的引用存储在局部变量1。

此后,该变量的作用域丢失,但是字节码没有说明清除其值的任何内容,因此在堆栈帧中保留了对该对象的引用。即使代码本身无法达到此特定的垃圾收集器,它也可以实现。

如果相反,您尝试分配另一个局部变量,例如

byte i = 1;

那么相应的字节码指令就像

    15: iconst_1          16: istore_1

其中

iconst_1
将值1存储在堆栈上,并将
istore_1
该值存储在变量1中,该变量似乎与以前相同。如果是,则您将覆盖它的值,对该
byte[]
对象的引用将丢失,然后该对象“成为”有资格进行垃圾回收。

最终证明

使用

-g
选项编译此代码

public class Driver {    private static final int dataSize = (int) (Runtime.getRuntime().maxMemory() * 0.6);    public static void main(String[] args) throws InterruptedException {        { System.out.println(dataSize); byte[] data = new byte[dataSize];        }        byte i = 1;        System.out.println(dataSize);        byte[] data2 = new byte[dataSize];    }}

然后运行

javap -c -l Driver
。你会看到
LocalVariableTable
这样的

LocalVariableTable:  Start  Length  Slot  Name   Signature   15       0     1    data   [B    0      33     0    args   [Ljava/lang/String;   17      16     1     i     B   32       1     2    data2  [B

其中槽是在索引中

astore_1
istore_1
。因此,
byte[]
当您为局部变量分配新值时,对的引用将被清除。即使变量具有不同的类型/名称,它们也以字节码形式存储在同一位置。



欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5130823.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-11-17
下一篇 2022-11-17

发表评论

登录后才能评论

评论列表(0条)

保存