如何删除 Java 中的(有效的)最终数组
How to delete an (effectively) final array in Java
我想在使用后通过 null
ing 删除对大数组的引用。然而,这给了我一个编译器错误,因为对数组的并行分配要求数组(有效地)是最终的(至少这是我认为的问题......)。我怎样才能允许垃圾回收删除数组?
double[][] arr = new double[n][n];
IntStream.range(0, n).parallel().forEach(i -> {
for(int j=0;j<i;j++) {
directDistances[i][j] = directDistances[j][i] = ...;
}
});
//Use arr here...
arr = null; //arr no longer needed.
//This gives the error "Local variable defined in an enclosing scope must be final or effectively final."
使用AtomicReference ar = new AtomicReference () ; ar. set(arr) ;
这将为您提供一个有效的最终数组
然后用ar.set()和ar.get()方法修改数组
最迟在方法 returns 时,数组 符合垃圾回收条件 - 您无需将其设置为 null。
如果您有一个很长的方法,并且担心数组的其余部分会被保留,解决方案是编写较小的方法。将功能划分为更小的方法也可以提高可读性和可重用性。
如果您不能或不想编写更小的方法,在方法中引入单独的块可能会有所帮助。局部变量声明对于块是局部的,因此这个“技巧”还可以让您 re-use 方法中不同块中的变量名。
void largeMethod() {
first: {
final int number = 1;
}
second: {
final int number = 2;
}
}
从技术上讲,数组在最后一次使用后符合垃圾回收条件,which can be in the middle of the method - before the variable goes out of scope. This is explicitly allowed by section 12.6.1 in the language specification:
Optimizing transformations of a program can be designed that reduce the number of objects that are reachable to be less than those which would naively be considered reachable. For example, a Java compiler or code generator may choose to set a variable or parameter that will no longer be used to null to cause the storage for such an object to be potentially reclaimable sooner.
虽然规范 允许 这种优化,但它 不需要 它。如果您发现在特定情况下没有进行优化并且您需要更好的保证,将大方法拆分为更小的方法会有所帮助。
I want to delete remove the reference to a large array by nulling the reference after I used it
不要。
我所知道的 JVM 世界中的所有实现都会扫描线程堆栈以找出可访问的对象。这意味着该方法的 scope nothing 与 Object 的存活时间无关。简单来说:
void yourMethod(){
byte [] bytes = ....
// use bytes array somehow
// stop using the byte array
// .... 10_000 lines of code
// done
}
紧跟在行 // stop using the byte array
之后,bytes
IS 符合垃圾回收条件。 在方法结束后,它将不符合条件。方法的 scope({
和 }
之间的所有内容)不会影响 bytes
存活的程度。 .
我想在使用后通过 null
ing 删除对大数组的引用。然而,这给了我一个编译器错误,因为对数组的并行分配要求数组(有效地)是最终的(至少这是我认为的问题......)。我怎样才能允许垃圾回收删除数组?
double[][] arr = new double[n][n];
IntStream.range(0, n).parallel().forEach(i -> {
for(int j=0;j<i;j++) {
directDistances[i][j] = directDistances[j][i] = ...;
}
});
//Use arr here...
arr = null; //arr no longer needed.
//This gives the error "Local variable defined in an enclosing scope must be final or effectively final."
使用AtomicReference ar = new AtomicReference () ; ar. set(arr) ;
这将为您提供一个有效的最终数组
然后用ar.set()和ar.get()方法修改数组
最迟在方法 returns 时,数组 符合垃圾回收条件 - 您无需将其设置为 null。
如果您有一个很长的方法,并且担心数组的其余部分会被保留,解决方案是编写较小的方法。将功能划分为更小的方法也可以提高可读性和可重用性。
如果您不能或不想编写更小的方法,在方法中引入单独的块可能会有所帮助。局部变量声明对于块是局部的,因此这个“技巧”还可以让您 re-use 方法中不同块中的变量名。
void largeMethod() {
first: {
final int number = 1;
}
second: {
final int number = 2;
}
}
从技术上讲,数组在最后一次使用后符合垃圾回收条件,which can be in the middle of the method - before the variable goes out of scope. This is explicitly allowed by section 12.6.1 in the language specification:
Optimizing transformations of a program can be designed that reduce the number of objects that are reachable to be less than those which would naively be considered reachable. For example, a Java compiler or code generator may choose to set a variable or parameter that will no longer be used to null to cause the storage for such an object to be potentially reclaimable sooner.
虽然规范 允许 这种优化,但它 不需要 它。如果您发现在特定情况下没有进行优化并且您需要更好的保证,将大方法拆分为更小的方法会有所帮助。
I want to delete remove the reference to a large array by nulling the reference after I used it
不要。
我所知道的 JVM 世界中的所有实现都会扫描线程堆栈以找出可访问的对象。这意味着该方法的 scope nothing 与 Object 的存活时间无关。简单来说:
void yourMethod(){
byte [] bytes = ....
// use bytes array somehow
// stop using the byte array
// .... 10_000 lines of code
// done
}
紧跟在行 // stop using the byte array
之后,bytes
IS 符合垃圾回收条件。 在方法结束后,它将不符合条件。方法的 scope({
和 }
之间的所有内容)不会影响 bytes
存活的程度。