public class Currency {
String name = new String();
static Integer value = new Integer();
static void getCurrency(Integer v) {
Currency c = new Currency();
c.value = v;
}
public static void m() {
Currency.getCurrency(50);
Currency.getCurrency(100);
}
public static void main(String[] argv) {
Currency.m();
}
}
当m()
退出时,我会计算5个符合垃圾收集器条件的元素。练习说6是正确的答案。你能救我吗?
答案 0 :(得分:1)
对getCurrency()
进行的两次调用将分别创建两个 Currency
个对象。每次通话都需要:
Integer
对象作为参数,稍后分配给value
Currency
对象name
字符串对象(不是static
,即每个Currency
对象都有一个)3×2 = 6
<强>更新强>
最大的问题似乎是,是否会为每次调用Integer
构造函数创建一个新的Currency
对象。将原始int
自动装箱到Integer
会调用Integer.valueOf()
。 Javadoc可以说Integer.valueOf()
:
返回表示指定int值的Integer实例。如果不需要新的Integer实例,通常应优先使用此方法,而不是构造函数Integer(int),因为此方法可能通过缓存频繁请求的值来显着提高空间和时间性能。 此方法将始终缓存-128到127(包括-128到127)范围内的值,并可以缓存此范围之外的其他值。
因此缓存了-128到127范围内的值。但问题是,在您的代码中,您正在使用两个不同的值,50和100,因此缓存不会避免创建新的Integer
对象AFAIK。
答案 1 :(得分:0)
我不同意接受的答案。我相信你对五个物品有资格进行垃圾收集的回答实际上是正确的,而你正在进行的练习是错误的(虽然如果有人能解释我是怎么弄错的,我会非常感激它。) / p>
以下是程序引用的对象:
Integer
#0 - 由Integer
* static Integer value = new Integer()
Currency
#1 - 由Currency
创建的Currency.getCurrency(50)
。Integer
#1 - Integer
自动装箱返回的50
。String
#1 - String
在String name = new String()
#1创建时创建的Currency
。Currency
#2 - 由Currency
创建的Currency.getCurrency(100)
。Integer
#2 - Integer
自动装箱返回的100
。String
#2 - String
在String name = new String()
#2创建时创建的Currency
。*这实际上并没有编译,但我认为它已经被有效的代码所取代,而这些代码对程序没有任何影响。
因此,您的代码需要七个对象才能运行。当value
被value
覆盖时,50
最初引用的对象有资格进行垃圾回收。当Currency
的唯一引用超出范围时,第一个和第二个m
符合条件。第一个和第二个String
符合条件m
,当他们唯一的引用对象Currency
s 1和2超出范围时。来自Integer
的自动装箱100
最后仍被静态参考value
引用,因此不符合垃圾回收条件。这5个对象符合条件,1个不合格,还有1个尚未讨论。
最后一个对象是Integer
自动装箱返回的50
。您的代码显然不再引用它,因为value
设置为引用100
。这似乎表明它有资格进行垃圾收集,但我不同意。 Integer
类is know to cache values at least in the range -128
to 127
以符合JLS 5.1.7。因此,当m
退出时,缓存仍会包含对来自Integer
的装箱50
的引用,导致它不符合垃圾回收的条件。
我尝试使用此程序测试此行为:
public class Test{
public static final WeakReference<Integer> inCache = new WeakReference<>(50);
public static final WeakReference<Integer> outOfCache = new WeakReference<>(10000);
public static void main(String[] args){
System.gc();
System.out.println(inCache.get());
System.out.println(outOfCache.get());
}
}
哪个输出
50
null
表明,至少在这种情况下,未缓存的Integer
被垃圾收集而缓存的50
没有收集。这表明,即使没有明确引用System.gc()
,由于缓存中存储的引用,它仍然没有资格进行垃圾收集。
我承认这并不能证明任何事情,因为,Integer
并不能保证它会收集所有(或任何)可用内存。但是,我认为这应该表明问题并不像人们想象的那样简单,而且在最常见的JDK / JVM上,第六个值不符合垃圾收集的条件是合理的。
TL; DR - 我不认为装箱50
返回的Integer
有资格进行垃圾收集,因为它仍由select * from events
where timestamp >= UNIX_TIMESTAMP( 06:00:00 AM)
and timestamp < UNIX_TIMESTAMP(05:59:59 AM)
维护的缓存引用类。