美文网首页Java
Java中的对象都是在堆中分配吗?

Java中的对象都是在堆中分配吗?

作者: WilsonMing | 来源:发表于2022-06-28 17:26 被阅读0次

为解答这个问题,我们要先了解对象逃逸相关内容。

什么是对象逃逸?

  • 一个对象的作用域仅限于方法区域内部在使用的情况下,此种状况我们叫非对象逃逸。
  • 一个对象如果被外部其他类调用,或者是作用于属性中,则此种现象被称之为对象逃逸。

对象逃逸:

/**
     * sb为逃逸对象,因为sb返回出去进行使用,所以发生逃逸
     *
     * @param s1
     * @param s2
     * @return
     */
    fun methodEscape(s1: String, s2: String): StringBuffer {
        var sb = StringBuffer()
        sb.append(s1)
        sb.append(s2)
        return sb
    }

非对象逃逸

/**
     * sb为非逃逸对象,因为方法方法返回的是一个新的String,而StringBuffer对象未产生逃逸现象
     *
     * @param s1
     * @param s2
     * @return
     */
    fun method(s1: String, s2: String): String {
        var sb = StringBuffer()
        sb.append(s1)
        sb.append(s2)
        return sb.toString()
    }

对于逃逸的对象他会分配到堆中,对于非逃逸的对象会在加载字节码后JIT编译优化。通过逃逸分析,如果是非逃逸对象,JIT可以有以下优化:

  • 1.栈上分配:JIT编译器在编译期间根据逃逸分析计算结果,如果发现当前对象没有发生逃逸现象,那么当前对象就可能被优化分配到栈上
  • 2.标量替换:有非逃逸对象可能不需要作为一个连续的内存结构存在也能被访问到, 那么对象部分可以不存储在内存,而是存储在CPU寄存器中。

标量替换

  • 标量:
    指一个无法在分解更小的数据的数据。在Java中的原始数据类型就是标量
  • 聚合量
    Java中的聚合量指的是类,封装的行为就是聚合。

标量替换其实就是把非逃逸的对象,在JIT优化分解为Java原始数据类型加载
如:

public class Paint {
    int count;
    int year;

    public static void main(String[] args) {
        Paint paint=new Paint();
    }
}

中的main方法JIT优化后

public class Paint {
    int count;
    int year;
    public static void main(String[] args) {
//        Paint paint=new Paint();
        int count=2;
        int year=10;
    }
}

逃逸分析的作用

  • 代码优化
    在编写代码的时候,尽可能的使用非逃逸对象方式,可以减少对象在堆上创建,非逃逸的对象创建在栈上,他会随着私有线程栈销毁就销毁。

逃逸分析的缺点

逃逸分析技术,至今还未完全成熟。原因是无法保证逃逸分析的性能消耗一定高于他的实际消耗,虽然经过逃逸分析可以做标量替换,栈上分配,锁消除等操作。但是逃逸分析自身也需要进行一系列的复杂分析算法的运算,这也是一个相对耗时过程。

Java中的对象都是在堆中分配吗?

通过的理解对象逃逸,我们在回答我们这个面试问题,答案:不是,在Java中如果对象是非逃逸对象,他们会优化分配到栈、寄存器中。

相关文章

  • Java中的对象都是在堆中分配吗?

    为解答这个问题,我们要先了解对象逃逸相关内容。 什么是对象逃逸? 一个对象的作用域仅限于方法区域内部在使用的情况下...

  • JVM对象的栈上分配

    前言 并不是所有对象都需要在堆中分配 栈上分配 Java虚拟机中,几乎所有创建的对象都是在堆中进行分配,并且分配在...

  • jvm逃逸分析

    首先先看一个问题,对象是否都被分配到了堆内存中? 众所周知java中对象都默认被分配到堆中,在栈中,只保存了对象的...

  • Java中的对象都是在"堆"中创建吗?

    https://www.cnblogs.com/CQqfjy/p/12690136.html

  • Java垃圾回收机制介绍

    Java垃圾回收机制 Java中对象是采用new或者反射的方法创建的,这些对象的创建都是在堆(Heap)中分配的,...

  • Java虚拟机 —— 垃圾回收机制

    在Java虚拟机中,对象和数组的内存都是在堆中分配的,垃圾收集器主要回收的内存就是再堆内存中。如果在Java程序运...

  • Java中堆和栈的区别

    堆和栈都是Java用来在RAM中存放数据的地方。 堆 (1)Java的堆是一个运行时数据区,类的对象从堆中分配空间...

  • java中堆和栈有什么区别?

    堆和栈都是Java用来在RAM中存放数据的地方。 一、堆 (1)Java的堆是一个运行时数据区,类的对象从堆中分配...

  • Java中堆和栈的区别

    堆和栈都是Java用来在RAM中存放数据的地方。 堆 1. Java的堆是一个运行时数据区,类的对象从堆中分配空间...

  • 堆外内存和虚引用

    堆外内存 概念 堆内内存在 Java 中对象都是在堆内分配的,通常我们说的JVM 内存也就指的堆内内存,堆内内存完...

网友评论

    本文标题:Java中的对象都是在堆中分配吗?

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