我爱编程

普遍的一些小问题

2018-06-21  本文已影响0人  哓晓的故事

Object大小

Object obj = new Object();
obj引用类型占用8 byte大小的栈空间
具体的对象占用的堆空间由对象决定

String拼接

StringBuffer append是线程安全的使用sychronized保证线程同步
StringBuilder 效率高,但是是非线程安全的
String 不可变的对象,每次对String进行操作的时候,都会生成一个新的对象,这会对系统的性能造成影响
StringBuilder和StringBuffer在处理拼接字符串的时候比+=效率高,因为一个是动态拼接,一个是静态拼接
每次+=""实际是重新开辟了内存空间来填充拼接后的字符串,会导致大量GC

JDK8针对+=""的拼接有做部分优化,在非fori的时候,会根据情况自动转义成StringBuilder/StringBuffer,但是在某些请款下还是不会变成有效的append方式,因此

因此在实际的使用中,当你无法区分字符串是静态拼接还是动态拼接的时候,还是使用StringBuilder/StringBuffer
如果能估算到字符串的长度, 尽可能去指定开辟的内存空间大小

String.intern()

s.intern()方法的时候,可能会导致永久代溢出, 因为会判断值是否存在永久代, 不存在则加入.

随机数Random

Random 虽然是线程安全的,是由于其对应的seed种子采用atomicLong保证了原子性,但是由于采用atomicLong在多线程竞争的时候会有性能损耗降低
SecureRandom 是继承Random的实现,本质上并发时也存在问题,但是随机性比Random好,除了使用系统时间外还使用了鼠标点击,键盘点击等等作为变量因子
ThreadLocalRandom 的SEED是无锁的,并发时不存在性能损耗

Java中的尾递归不支持优化

尾递归定义:

  1. 调用自身函数(Self-called)
  2. 计算仅占用常量栈空间(Stack Space)
  3. 调用在函数结束前最后一行, 只包含函数调用

Java到jdk8还是不支持尾递归(kotlin支持),不支持尾递归而使用了尾递归的写法,会导致深层次的线程棧帧嵌套最后导致stack overflow,以下代码是尾递归写法,在jdk编译的时候使用的是重复执行对应方法,在kotlin编译的时候会将递归改造成fori循环

public static int sum(int start, int end , int acc){
    if(start > end){
       return acc;
    }else{
       return sum(start + 1, end, start + acc);
    }
}

成员(实例)变量 + 类(静态)变量 + 局部变量

成员变量

类变量

局部变量

上一篇 下一篇

猜你喜欢

热点阅读