美文网首页我爱编程
普遍的一些小问题

普遍的一些小问题

作者: 哓晓的故事 | 来源:发表于2018-06-21 01:55 被阅读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);
        }
    }
    

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

    成员变量

    • 随着对象创建存在,回收释放
    • 只能被对象调用
    • 存储在堆内存 heap
    • 无初始化

    类变量

    • 随着类加载存在,类消失消失
    • 能被对象/类名调用
    • 存储在方法区 method area(共享数据区)
    • 无需初始化

    局部变量

    • 随着线程栈stack frame存在,释放
    • 只能在线程栈内部调用
    • 存储在栈 thread stack
    • 需要初始化

    相关文章

      网友评论

        本文标题:普遍的一些小问题

        本文链接:https://www.haomeiwen.com/subject/mupddftx.html