I'm trying to understand what the -XX:G1ReservePercent
actually does. The descriptions I found in the official documentation are not really comprehensive:
Sets the percentage of reserve memory to keep free so as to reduce the risk of to-space overflows. The default is 10 percent. When you increase or decrease the percentage, make sure to adjust the total Java heap by the same amount.
and the desciption of to-space exhausted log entry is this:
When you see to-space overflow/exhausted messages in …
我对Scala很新,并尝试理解可变性Seq
.因为它在包中mutable
我期望有一种方法允许我们在不复制整个集合的情况下追加元素.
但是没有+=
方法mutable.Seq
,但是在Buffer
.:+
并+:
复制该集合.
那为什么它是可变的?
我对Java中的匿名类有什么误解.考虑以下简单示例:
public static void main (String[] args) throws java.lang.Exception
{
B b = new B(){ };
System.out.println(b.b);
}
interface B{ int b = 1; }
Run Code Online (Sandbox Code Playgroud)
为什么代码编译?在JLS,CHAPT 15说:
匿名类始终是内部类(第8.1.3节); 它永远不会是静止的
内部类是未显式或隐式声明为静态的嵌套类.
所以匿名类是一个内部类.但我们在静态环境中使用它们.为什么在这里是正确的?
J. Bloch在撰写的Effective Java中Java 6
提到了以下内容(第17项):
如果您认为必须允许从这样的类继承,一种合理的方法是确保该类永远不会调用其任何可覆盖的方法并记录此事实.换句话说,完全 消除了类对可覆盖方法的自我使用.
第18项:
如果您使用抽象类来定义类型,那么您可以让想要添加功能的程序员别无选择,只能使用继承.结果类比包装类更强大,更脆弱.
虽然不允许接口包含方法实现,但使用接口来定义类型并不会阻止您向程序员提供实现帮助.
现在Java 8
使用其默认方法的实现(使用接口中的其他方法)接口对于继承是危险的.
例如:
public inteface MyInterface{
public void compute(Object o);
public default void computeAll(List<Object> oo){
for(Object o: oo)
compute(o); //self-use
}
}
Run Code Online (Sandbox Code Playgroud)
因此,根据J. Bloch的说法,当我们尝试实现接口时,它可能会引入一些问题,因为:
覆盖这样的方法(类似于J.Bloch提供的):
public class MyInterfaceCounter implements MyInterface{
private int count = 0;
@Override
public void compute(Object o) {
count++;
}
@Override
public void computeAll(List<Object> oo){
count += oo.size(); //Damn!!
MyInterface.super.computeAll(oo);
}
}
Run Code Online (Sandbox Code Playgroud)客户端访问接口的内部,即他们必须知道默认实现.
在Java 8中如何处理它?Effective Java的规则是否适用仍然适用?
而且,我们不能将默认方法声明为final
(因为我们可以对类进行声明,它会使自用对于重写器来说不太危险).
我有以下枚举:
enum Days{
TODAY{
@Override
public Date getLowerBound(){
another(); //1
currentUpperBound(); //2
return null;
}
@Override
public Date another() {
return null;
}
};
public abstract Date getLowerBound();
public abstract Date another();
private Date currentUpperBound(){
return null;
}
}
Run Code Online (Sandbox Code Playgroud)
为什么//2
导致编译时错误
Cannot make a static reference to the non-static method
currentUpperBound() from the type Days
Run Code Online (Sandbox Code Playgroud)
但//1
编译好吗?两种方法都是非静态的.我看不出任何问题......也许它与Eclipse有关?
更新:正如@Florian Schaetz在评论中注意到的,如果我们声明方法有static private
修饰符,它将正常工作.为什么?
PostgreSQL 9.4
我刚刚遇到了这个帖子中Bitmap Index Scan
提到的被调用的节点和所谓的底层位图数据结构的概念.据我所知,不支持创建位图索引.PostgreSQL
问:所以每当我们需要使用位图数据结构来执行时Bitmap Index Scan
,我们需要先构建它,或者PostgreSQL在构造btree
索引时创建它并在表更改时重建它吗?
我的意思是,有什么好的理由吗?该方法得到以下签名:
public static Object newInstance(Class<?> componentType,
int length)
throws NegativeArraySizeException
Run Code Online (Sandbox Code Playgroud)
在我看来,将方法声明如下更方便:
public static <T> T[] newInstance(Class<T> componentType, int length)
throws NegativeArraySizeException
Run Code Online (Sandbox Code Playgroud)
这样,当创建泛型类型的aray时,执行额外的转换是不必要的,例如
public class Gen<T>{
private T[] a;
public static <T> Gen<T> createByClass(Class<T> clazz){
a = clazz.cast(Array.newIntance(clazz.getComponentType(), 8); //we have to invoke
//clazz.cast here.
}
}
Run Code Online (Sandbox Code Playgroud)
是否有充分的理由将返回值类型声明为Object
?对我而言似乎非常不耐烦.
J. Bloch在他的有效Java中为equals方法的实现提供了几条规则.他们来了:
•Reflexive:对于任何非空引用值x,x.equals(x)必须返回true.
•对称:对于任何非空引用值x和y,当且仅当y.equals(x)返回true时,x.equals(y)必须返回true.
•Transitive:对于任何非空引用值x,y,z,如果x.equals(y)返回true而y.equals(z)返回true,则x.equals(z)必须返回true.
•一致:对于任何非空引用值x和y,x.equals(y)的多次调用始终返回true或始终返回false,前提是不修改在对象上的equals比较中使用的信息.
•对于任何非空引用值x,x.equals(null)必须返回false.
但后来他在书中提到了所谓的利斯科夫替代原则:
Liskov替换原则表明类型的任何重要属性也应该适用于其子类型,因此为该类型编写的任何方法在其子类型上应该同样有效
我不知道它与equals
合同的关系.我们是否应该在编写equals实现时坚持它?
问题是关于实现子类的方法.以下是本书中的示例:
private static final Set<Point> unitCircle;
static {
unitCircle = new HashSet<Point>();
unitCircle.add(new Point(1, 0));
unitCircle.add(new Point(0, 1));
unitCircle.add(new Point(-1, 0));
unitCircle.add(new Point(0, -1));
}
public static boolean onUnitCircle(Point p) {
return unitCircle.contains(p);
}
public class CounterPoint extends Point {
private static final AtomicInteger counter = new AtomicInteger();
public CounterPoint(int x, int y) {
super(x, y);
counter.incrementAndGet();
}
public int numberCreated() { return counter.get(); }
}
Run Code Online (Sandbox Code Playgroud)
以及以下实施:
// …
Run Code Online (Sandbox Code Playgroud) 考虑以下课程:
public abstract class AbstractClass {
public abstract String m();
public AbstractClass get(){
return new AbstractClass() {
@Override
public String m() {
return "Anonymous " + super.m(); //1, Compile-time erro
}
};
}
}
Run Code Online (Sandbox Code Playgroud)
目前尚不清楚为何super
禁止这种使用.在//1
,发生以下错误
Cannot directly invoke the abstract method m() for the type AbstractClass
Run Code Online (Sandbox Code Playgroud)
所以,我咨询了JLS 15.11.2并没有找到阻止这些代码编译的限制.他们来了:
如果使用关键字super的表单出现在Object类的声明中,那么这是一个编译时错误,因为Object没有超类.
AbstractClass
,但只有一个具体的子类,以下似乎也是有效的:使用关键字super的表单仅在实例方法,实例初始值设定项或构造函数中有效,或在类的实例变量的初始值设定项中有效.如果它们出现在其他任何地方,则会发生编译时错误.
如果当前类不是类T或T本身的内部类,则它是编译时错误.
当然,我可以使用AbstractClass.this.m()
,但这不是我要问的.
我正在玩,jmh
在关于循环的部分他们说
您可能会注意到重复次数越多,所测量操作的"感知"成本就越低.到目前为止,我们每增加1/20 ns,远远超出硬件实际可行的范围.发生这种情况是因为循环被大量展开/流水线化,并且要从循环中提升要测量的操作.士气:不要过度使用循环,依靠JMH来获得正确的测量.
我亲自尝试过
@Benchmark
@OperationsPerInvocation(1)
public int measurewrong_1() {
return reps(1);
}
@Benchmark
@OperationsPerInvocation(1000)
public int measurewrong_1000() {
return reps(1000);
}
Run Code Online (Sandbox Code Playgroud)
得到以下结果:
Benchmark Mode Cnt Score Error Units
MyBenchmark.measurewrong_1 avgt 15 2.425 ± 0.137 ns/op
MyBenchmark.measurewrong_1000 avgt 15 0.036 ± 0.001 ns/op
Run Code Online (Sandbox Code Playgroud)
它确实表明它MyBenchmark.measurewrong_1000
比它快得多MyBenchmark.measurewrong_1
.但我无法真正理解JVM在提高性能方面所做的优化.
他们的意思是循环展开/流水线?
java ×8
arrays ×1
bitmap ×1
collections ×1
enums ×1
equals ×1
g1gc ×1
generics ×1
indexing ×1
inheritance ×1
java-8 ×1
jmh ×1
jvm ×1
loops ×1
performance ×1
postgresql ×1
scala ×1
sql ×1
super ×1