- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
public void testWeak() throws Exception {
waitGC();
{
Sequence a = Sequence.valueOf("123456789");
assert Sequence.used() == 1;
a.toString();
}
waitGC();
}
private void waitGC() throws InterruptedException {
Runtime.getRuntime().gc();
short count = 0;
while (count < 100 && Sequence.used() > 0) {
Thread.sleep(10);
count++;
}
assert Sequence.used() == 0: "Not removed!";
}
测试失败。告诉 未删除!
。
public void testAWeak() throws Exception {
waitGC();
extracted();
waitGC();
}
private void extracted() throws ChecksumException {
Sequence a = Sequence.valueOf("123456789");
assert Sequence.used() == 1;
a.toString();
}
private void waitGC() throws InterruptedException {
Runtime.getRuntime().gc();
short count = 0;
while (count < 100 && Sequence.used() > 0) {
Thread.sleep(10);
count++;
}
assert Sequence.used() == 0: "Not removed!";
}
似乎大括号并没有影响弱点。
一些官方资源?
最佳答案
作用域是编译时的东西。它不决定对象在运行时的可达性,仅对实现细节有间接影响。
考虑以下测试变体:
static boolean WARMUP;
public void testWeak1() throws Exception {
variant1();
WARMUP = true;
for(int i=0; i<10000; i++) variant1();
WARMUP = false;
variant1();
}
private void variant1() throws Exception {
AtomicBoolean track = new AtomicBoolean();
{
Trackable a = new Trackable(track);
a.toString();
}
if(!WARMUP) System.out.println("variant1: "
+(waitGC(track)? "collected": "not collected"));
}
public void testWeak2() throws Exception {
variant2();
WARMUP = true;
for(int i=0; i<10000; i++) variant2();
WARMUP = false;
variant2();
}
private void variant2() throws Exception {
AtomicBoolean track = new AtomicBoolean();
{
Trackable a = new Trackable(track);
a.toString();
if(!WARMUP) System.out.println("variant2: "
+(waitGC(track)? "collected": "not collected"));
}
}
static class Trackable {
final AtomicBoolean backRef;
public Trackable(AtomicBoolean backRef) {
this.backRef = backRef;
}
@Override
protected void finalize() throws Throwable {
backRef.set(true);
}
}
private boolean waitGC(AtomicBoolean b) throws InterruptedException {
for(int count = 0; count < 10 && !b.get(); count++) {
Runtime.getRuntime().gc();
Thread.sleep(1);
}
return b.get();
}
在我的机器上,它打印:
variant1: not collected
variant1: collected
variant2: not collected
variant2: collected
如果无法复现,可能需要提高预热迭代次数。
它演示了什么:a
是否在范围内(变体 2)或不在范围内(变体 1)无关紧要,在任何一种情况下,对象都没有在冷执行中被收集,但是得到了在多次预热迭代后收集,换句话说,在优化器启动后收集。
形式上,a
在我们调用 waitGC()
时总是有资格进行垃圾回收,因为它未被使用观点。这是 how reachability is defined :
A reachable object is any object that can be accessed in any potential continuing computation from any live thread.
在此示例中,潜在的连续计算无法访问该对象,因为不存在可访问该对象的此类后续计算。但是,无法保证特定 JVM 的垃圾收集器每次始终能够识别所有这些对象。事实上,即使 JVM 根本没有垃圾收集器也仍然符合规范,尽管可能不是本意。
代码优化对可达性分析产生影响的可能性也已明确 mentioned in the 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.
那么技术上会发生什么?
如前所述,范围是编译时的事情。在字节码级别,离开花括号定义的范围没有任何效果。变量 a
超出范围,但它在堆栈帧中的存储仍然存在并保存引用,直到被另一个变量覆盖或直到方法完成。编译器可以自由地为另一个变量重用存储,但在这个例子中,不存在这样的变量。因此,上面示例的两个变体实际上生成了相同的字节码。
在未优化的执行中,堆栈帧中仍然存在的引用被视为阻止对象收集的引用。在优化执行中,引用仅保留到最后一次实际使用为止。内联它的字段可以允许它的收集甚至更早,直到它在构造后立即被收集(或者根本没有被构造,如果它没有 finalize()
方法)。最末端是finalize() called on strongly reachable object in Java 8 ……
当您插入另一个变量时,情况会发生变化,例如
private void variant1() throws Exception {
AtomicBoolean track = new AtomicBoolean();
{
Trackable a = new Trackable(track);
a.toString();
}
String message = "variant1: ";
if(!WARMUP) System.out.println(message
+(waitGC(track)? "collected": "not collected"));
}
然后,a
的存储在 a
的范围结束后被 message
重用(这当然是特定于编译器的)并且即使在未优化的执行中,对象也会被收集。
请注意,关键方面是存储的实际覆盖。如果你使用
private void variant1() throws Exception {
AtomicBoolean track = new AtomicBoolean();
{
Trackable a = new Trackable(track);
a.toString();
}
if(!WARMUP)
{
String message = "variant1: "
+(waitGC(track)? "collected": "not collected");
System.out.println(message);
}
}
message
变量使用与 a
相同的存储空间,但它的赋值只发生在 调用 waitGC(track) 之后
,因此您将获得与原始变体相同的未优化执行行为。
顺便说一句,不要对局部循环变量使用short
。 Java 始终使用 int
进行 byte
、short
、char
和 int
计算(如您所知,例如,当尝试编写 shortVariable = shortVariable + 1;
时,并要求它将结果值剪切为 short
(当您使用 shortVariable++
), 添加了一个附加操作,所以如果您认为使用short
可以提高效率,请注意它实际上是相反的。
关于java - WeakReference 没有收集在大括号中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47326757/
引用网址 http://hi.baidu.com/quiteuniverse/blog/item/9f3f043d46ad1e07bba16716.html 以下函数调用方式:&nbs
我什至不确定如何描述我正在尝试做的事情,因为我对 cookie 了解不多,但就这样吧。 是否可以使用PHP从浏览器缓存中收集一个cookie(或cookie文件),将其保存到数据库中,然后清除缓存并重
我正在使用 Room(v. 2.2.1)和协程支持(v. 1.3.2)并进行以下设置 @Entity(tableName = "simple_table") data class SimpleEnti
我正在尝试编写一个基于时间运算符收集/累积值的规则。 rule "Zone6 Overlap" when $i1 : Instance ($e1 : event == " Vel : 20.9
我有一个简单的 BST,定义了节点结构: struct node { int key_value; struct node *left; struct node *right; }; ty
我有这个对象: public class MenuPriceByDay implements Serializable { private BigDecimal avgPrice; p
我正在开发一个应用程序,需要访问给定传感器的“最后 5 秒有值(value)的数据”。我的计划是以某种方式存储这些数据,然后当我请求数据时,它将返回最近 5 秒内获得的所有数据。鉴于以下情况,我不确定
在 Ruby 中,您可以对数组使用 map/collect 方法来修改它: a = [ "a", "b", "c", "d" ] a.collect! {|x| x + "!" } a
我即将开始实时收集大量数字数据(对于那些感兴趣的人,各种股票和 future 的出价/要价/最后或“磁带”)。稍后将检索数据以进行分析和模拟。这一点都不难,但我想高效地做到这一点,这会带来很多问题。我
我提出这个问题是为了寻求有关如何设计系统的实用建议。 像 amazon.com 和 pandora 这样的网站拥有并维护着庞大的数据集来运行他们的核心业务。例如,亚马逊(以及所有其他主要电子商务网站)
假设我们有一个数据数组和另一个带索引的数组。 data = [1, 2, 3, 4, 5, 7] index = [5, 1, 4, 0, 2, 3] 我们想从 index 的 data 元素创建一个
好的,我已经阅读了几个关于它的主题,但现在就开始吧。假设我有一个应用程序,基本上我会时不时地点击一个按钮,几分钟内会发生很多事情,然后它可能会再闲置一个小时,或者可能只是 1 分钟。难道不是在整个结束
我有一个数据框,例如 Seq Chrm start end length score 0 A C1 1 50 49 12 1 B
我正在考虑在 Object[] 数组中收集泛型方法的所有方法参数以进行记录。我知道使用方面可以更好地实现这一点,但是我不允许使用它,并且如果可能的话我正在寻找一种基于纯反射的方法 为了澄清, 假设一个
快速提问: 如果 Socket 对象(及其本地缓存的 InputStream 和 OutputStream 对象)超出范围并被垃圾收集,连接是否在 JVM 中保持打开状态? (即,不会在监听服务器上抛
是否有用于收集 facebook 公共(public)数据作为实时提要的 API。我阅读了关于用于收集数据的公共(public)提要 API,但我现在不能申请,而且它不是免费的,还有 Open str
摘要 :我使用自定义收集器收集给定搜索的所有命中的文档 ID(它使用 ID 填充 BitSet)。根据我的需要,搜索和获取文档 ID 的速度非常快,但是当涉及到从磁盘实际获取文档时,事情变得非常缓慢。
我正在寻找一种方法来从自定义 Gradle 插件收集给定项目的所有依赖约束(通过常规 platform 和/或 enforcedPlatform 和/或“手动”强制执行)。 在 Maven 世界中,您
我有一个 CSV 格式的用户列表,但我需要按广告中的名称从每个用户收集 SamAccount 属性。 CSV 模型 脚本 Get-ADObject -Filter 'ObjectClass -eq "
我得到了一个非常大的列表,其中包含大约 200 个带有文本和图像的项目。 ng-repeat 是一种缓慢渲染的方式。它尝试过这个 solution 。效果很好。但不适合重复收集。 我的网络服务返回此:
我是一名优秀的程序员,十分优秀!