精华内容
下载资源
问答
  • 对象在哪里
    千次阅读
    2021-02-28 12:42:41

    对象存储位置

    程序运行时,对象是怎么放置安排的呢?特别是内存是怎样分配的呢?有五个不同的地方可以存储数据:

    1.寄存器

    寄存器是最快的存储区,位于处理器内部。但是寄存器的数量极其有限,所以寄存器根据需求进行分配。人为不可控制,也不能在程序中感觉到寄存器存在的任何迹象。

    2.堆栈

    堆栈位于通用RAM(随机访问存储器)中,但通过堆栈指针可以从处理器那里获得直接支持。堆栈指针若向下移动,则分配新的内存;若向上移动,则释放那些内存。这是一种快速的分配存储方法,仅次于寄存器。创建程序时,Java系统必须知道存储在堆栈内所有项的确切生命周期,以便上下移动堆栈指针。这一约束了程序的灵活性,所以虽然某些Java数据存储于堆栈中——特别是对象引用,但是Java对象并不存储于其中。

    3.堆

    堆是一种通用的内存池(也位于RAM区),用于存放所有的Java对象。堆不同于堆栈的好处是:编译器不需要知道存储的数据在堆里存活多长时间。因此,在堆里分配存储有很大的灵活性。当需要一个对象时,只需用new写一行代码,当执行这行代码时,会自动在堆里进行存储分配。当然,为这种灵活性必须付出代价:用堆进行分配和清理可能比用堆栈进行存储分配需要更多的时间。

    4.常量存储

    常量值通常直接存储在程序代码内部,这样做是安全的,因为它们永远不会被改变。有时,在嵌入式系统中,常量本身会和其他部分隔离开,所以在这种情况下,可以选择将其存放在ROM中(只读存储器)。

    5.非RAM存储

    如果数据完全存活于程序外,那么它可以不受程序的任何控制,在程序没有运行时也可以存在。其中两个最基本的例子是流对象和持久化对象。在流对象中,对象转化成字节流,通常被发送给另一台机器。在持久化对象中,对象被存储于磁盘中,在程序需要时,可恢复成常规的,基于RAM的对象(例如JDBC和Hibernate)。

    更多相关内容
  • pycharm中查找一个对象在哪里被引用

    万次阅读 2018-10-28 19:22:20
    要查找的对象上右键-》Find Usages-》界面下方会列出查找结果。 快捷键:Alt + F7 下面以test.py和test2.py为例,其中test2.py使用了test.py的foo函数 文件test.py中,把鼠标放到foo上面再右键点击Find Usages。...

    PyCharm的Find Usages功能可以查找某个对象(变量、函数、或者类等)被引用的地方

    使用:
    在要查找的对象上右键-》Find Usages-》界面下方会列出查找结果。
    快捷键:Alt + F7

    下面以test.py和test2.py为例,其中test2.py使用了test.py的foo函数

    在文件test.py中,把鼠标放到foo上面再右键点击Find Usages。

    查找结果如下图所示,可以看出foo()函数被引用了3次,其中test2.py引用了2次,test3.py引用了1次

    展开全文
  • Class对象存储Java堆中

    千次阅读 2021-11-15 16:50:15
    JDK1.8完全废除永久代之前的... 众所周知, java中new处的对象存放java堆中,而对象的引用存放虚拟机栈中。 Java中的Class也是一个类,所以Class对象也存放堆当中,存放方法区当中的是Class对象的引用 ...

            在JDK1.8完全废除永久代之前的JDK版本中,方法区是一个逻辑分区,实际是java堆的一部分,但是有Non-heap的标记,以便区分。

           众所周知, java中new处的对象存放在java堆中,而对象的引用存放在虚拟机栈中。

            Java中的Class也是一个类,所以Class对象也存放在堆当中存放在方法区当中的是类的元数据,即类加载器从class文件中提取出来的类型信息、方法信息、字段信息等。

            Java的对象(包括class对象)中保存着指向相应类的元数据的引用,元数据中又保存着指向class对象的引用。

    OOP-KLASS内存模型Class实例在堆中还是方法区中? - 小菜变大鸟 - 博客园

            在JVM中,使用了OOP-KLASS模型来表示java对象

            JVM加载一个类的时候会创建一个instanceKlass,用来表示这个类的元数据,包括常量池、字段、方法等。存放在方法区

            在new一个对象时,jvm创建instanceOopDesc,来表示这个对象,存放在区,其引用,存放在栈区;平时说的Java Object Layout就是instanceOopDesc,它用来表示对象的实例信息;instanceOopDesc对应java中的对象实例。

            HotSpot并没有把instanceKlass直接暴露给Java,而会另外创建对应的instanceOopDesc来表示java.lang.Class对象,并将后者称为前者的“Java镜像”,instanceKlass持有指向instanceOopDesc的引用。(_java_mirror便是该instanceKlass对Class对象的引用);

    instanceOopDesc包含三部分:
    1. 对象头,也叫Mark Word,主要存储对象运行时记录信息,如hashcode, GC分代年龄,锁状态标志,线程ID,时间戳等;
    2. 元数据指针,即指向方法区的instanceKlass实例
    3. 实例数据;
    4. 另外,如果是数组对象,还多了一个数组长度

    总结:

    • instanceKlass保存类的元数据,存储在方法区,只有一份(同一个类加载器)。
    • instanceOopDesc保存类实例对象包括class对象),存储在堆中。一个类的实例对象可以有多个,但class对象只有一个(同一个类加载器),一个类的class对象与其类的元数据一一对应。
    • instanceOopDesc中包含指向相应的instanceKlass(类的元数据)的指针,而instanceKlass又保存着相应class对象(instanceOopDesc)的引用。
    • HotSpot通过InstanceOopDesc将类的元数据通过class对象间接暴露给java,class对象是java访问类的元数据的入口(因为class对象(InstanceOopDesc)中保存着指向元数据的指针)。
    • Person类的实例(Oop)-->Person类的元数据()-->Person类的class对象:解读(前提:同一个类加载器)
      • 每一个类的实例可以有多个,每个实例对象对应的Oop中对klass的引用都是同一个
      • 每一个类的元数据instanceKlass只有一个
      • 每一个类的class对象(Oop)也只有一个
      • 唯一的Klass与唯一的class对象一一对应,互相保存着对彼此的引用。
    •  不同类加载器产生的class对象不同,分布在堆中的不同地址中。
    • 这些引用关系支持着获取class对象三种方式的实现
      •  Class.forName("ClassName"):通过类的元数据中的class对象引用获得class对象
      •  object.getClass():通过实例对象中保存的对类的元数据的引用获取类的元数据(instanceKlass),通过instanceKlass中对class对象的引用获取class对象(instanceOopDesc)
      •  ClassName.class:通过类的元数据中的class对象引用获得class对象
    • Oop中对klass的引用支持【通过class对象创建类的实例对象】这一功能的实现

     

    展开全文
  • Java对象的内存是在哪里分配的?

    千次阅读 2020-09-11 21:12:20
    对于绝大多数对象,内存的确是堆中分配的,但是随着JIT编译器的进步、逃逸分析技术的成熟,“Java对象都是堆中分配内存”这个结论变得不是那么绝对了。 针对Java的内存分配策略,笔者这里画了一张简图如下: 栈...

    Java内存分配策略

    当我们使用new关键字去实例化一个对象时,对象的内存在哪里分配?

    相信很多Java程序员给出的答案都是【堆】,但事实并非绝对如此,JVM为此做了许多优化。

    对于绝大多数对象,内存的确是在堆中分配的,但是随着JIT编译器的进步、逃逸分析技术的成熟,【Java对象都是在堆中分配内存】这个结论变得不是那么绝对了。

    针对Java的内存分配策略,笔者这里画了一张简图如下:
    在这里插入图片描述

    栈上分配

    当实例化的对象占用的内存空间较小,且对象没有发生逃逸时,JVM就可以直接进行【栈上分配】优化,即对象的内存空间分配在栈上,而不是堆上。
    这样做的好处是:对象可以随着方法运行结束时栈帧的出栈而被销毁,不需要GC介入处理,减轻GC的压力。

    如下代码,频繁的创建byte数组,由于allocate()将数组赋值给了静态变量,使得其他线程可以访问到,即对象发生了线程逃逸,使得JVM无法进行栈上分配,只能分配在堆上,这时候就导致GC需要不断的清理对象,导致系统停顿时间过长。
    在这里插入图片描述
    如下,是堆上分配的GC情况。
    在这里插入图片描述

    注释赋值语句,对象不能逃逸,测试结果如下:
    在这里插入图片描述
    可以看到,【栈上分配】可以极大的减轻GC的压力,减少GC的停顿时间,提高系统的性能和吞吐量。

    大对象进入老年代

    当实例化的对象占用内存非常大时,JVM也会做优化,优先将其分配进老年代,而不是新生代。
    原因是:首先Eden区不一定能装得下大对象,其次,就算Eden区能装的下,如果经历一次GC后大对象没有被回收,由于新生代使用的是标记复制算法,JVM会将其复制到其中一个Survivor区,大对象的复制开销是比较大的,而且Survivor区空间通常很小,很难容纳大对象。如果把大对象放入Survivor区,会导致其他小对象难以复制,影响新生代的标记复制算法的正常工作。

    如下代码,证明了这个结论:
    在这里插入图片描述
    在实际开发中,还是应该尽量避免使用大对象,例如:长度很大的数组。
    使用大对象会增加JVM的压力,大对象通常较难以回收,要想回收大对象JVM就不得不触发Full GC,效率还是很低的。

    TLAB快慢分配

    当实例对象不能在栈上分配内存时,JVM就只能将其分配到堆了,即便如此,JVM依然可以做很多优化。
    由于对象的创建是非常频繁的行为,可能存在多个线程并发的创建对象,如果不做同步处理,可能会导致多个实例申请同一块内存。

    JVM可以选择通过加锁来分配内存,但是这样性能较低,于是就有了TLAB分配。

    TLABThread Local Allocation Buffer)本地线程分配缓冲区,每个线程会首先向OS申请一大块内存作为私有的内存缓冲区,当创建对象需要申请内存时,优先从内存缓冲区中进行分配,由于是线程私有的,不存在并发问题,速度会非常快。这样只有当内存缓冲区不够用时,线程才会同步的向OS申请内存,大大减少了锁的争用。

    如下代码,开启10个线程并发创建一千万个对象,分别开启和禁用TLAB进行测试:
    在这里插入图片描述
    测试结果如下:

    是否开启TLAB耗时(ms)
    1697
    12070

    可以看到,开启TLAB后可以获得7倍多的性能提升,效果还是很明显的。

    创建对象时,为了避免JVM进行栈上分配看不到效果,记得把对象赋值给静态变量,或者关闭JVM逃逸分析。

    展开全文
  • class对象存在于哪里?要怎么获取?

    千次阅读 2021-03-13 22:15:35
    你们知道class对象创建后是存放在哪里的吗?下面就来跟小编一起了解一下吧。什么是class对象?一个Class类,它被创建后的对象就叫做Class对象。Class对象表示的是自己手动编写类的类型信息,如创建一个Person 类,那么...
  • java对象在jvm中的存储情况 jvm
  • JavaScript内置对象

    千次阅读 2022-03-11 16:47:29
    第三个浏览器对象属于 JS 独有的, JS API 讲解内置对象就是指 JS 语言自带的一些对象,这些对象供开发者使用,并提供了一些常用的或是**最基本而必要的功能**(属性和方法),内置对象最大的优点就是帮助我们快速...
  • EXCEL对象应用.rar

    2020-04-04 20:37:04
    EXCEL对象应用.rar EXCEL对象应用.rar EXCEL对象应用.rar EXCEL对象应用.rar EXCEL对象应用.rar EXCEL对象应用.rar
  • 对象里面的对象

    千次阅读 2020-12-04 11:03:10
    1.Java中一定要认识到:一个对象变量并没有实际包含一个对象,而仅仅引用一个对象。 2.任何对象变量的值都是对存储另外一个地方的一个对象的引用。 3.new操作符的返回值也是一个引用。 ...
  • Java对象在哪里创建

    千次阅读 2017-04-08 18:38:01
    对象在哪里创建?  Java数据存储在哪里? 1,寄存器,存取速度最快,在cpu里面 2,堆栈,地址引用放栈里,对象放堆里,Java中的引用可以理解为c中的指针 3,堆,方面灵活但是缺点是比较耗内存(何时清除?)...
  • JavaScript 之面向对象

    千次阅读 多人点赞 2022-03-02 17:49:07
    JavaScript 面向对象 一、面向对象编程介绍 1.1 两大编程思想 面向过程 面向对象 1.2 面向过程编程 POP(Process-oriented programming) 面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤...
  • 局部对象和全局对象

    千次阅读 2020-03-25 16:00:36
    c++环境下讨论局部对象和全局对象局部对象全局对象代码展示 局部对象 语块句中定义的对象称为局部对象,包括函数的形参。局部对象相应的语句块内部可见,而且还会屏蔽外层作用域中的同名对象。 1、自动对象 ...
  • 每个类在加载的时候都会创建一个字节码对象,或者换一种说法,将类读到内存的时候都会创建一个字节码对象,其类型为Class类型,且这个对象在一个JVM 中是唯一的,此对象存储的是类的结构信息(元数据信息)。...
  • Java中对象的实例化

    千次阅读 2022-03-25 20:30:39
    对象:内存上来说是分配堆上面的一块内存区域 类:把一类具体事物相同特征,功能/行为抽象为属性与方法过程。 类是对象的模板,对象是类的具体表现。 构造函数:与类名同名的函数,用来实例化对象并初始化成员...
  • 我的同事问了一个非常有趣的问题,我无法给他答案。假设我们有以下课程:public class Person {String name;public Person(String name) {this.name = name;...}}现在,我们正在创建对象:Person p1 = new Person("a"...
  • 用引用操控对象创建对象创建的对象存储什么地方? 创建对象 拥有一个引用,并不一定需要有一个对象与他关联。因此,如果想要操作一个词或句子,则可以创建一个String引用: String s;//创建一个引用,但是这里所...
  • JDK7的官方解释:Currently static fields are stored in the instanceKlass but when those are moved into native memory we'd have to have a new card mark strategy for static fields. This could be ...
  • java的对象存储在哪里

    千次阅读 2020-02-29 14:29:17
    1、寄存器 寄存器是速度最快的存储区域,...常用于存放对象引用与基本数据类型,不存放Java对象。栈内存被要求存放其中的数据的大小、生命周期必须是已经确定的。 3、堆 通用的内存池,位于RAM中,用于存放所有的...
  • 数据库对象包括哪六个?

    千次阅读 2021-01-28 03:36:04
    数据库对象包括:用户(对数据库有权限访问的人)、视图(显示用户需要的数据项)、索引(给用户提供快速访问数据的途径...视图(View)视图也有一组数据项和命名字段,只是用户执行查询操作的时候才会出现,其实数据库...
  • Oracle数据库对象--视图

    千次阅读 2021-05-02 01:05:17
    视图以select语句的形式存储数据字典中。视图的优点1.由于视图能够选择性地显示表中的列,因而可以限制对数据的访问。2.视图可以用来进行简单的查询,从而检索复杂查询的结果。例如,用户可以通过视图查询多个表中...
  • Java中对象存储位置 - 堆和栈

    千次阅读 2021-03-09 15:59:45
    1. 栈(stack)与堆(heap)都是Java用来Ram中存放数据的地方。与C++不同,Java自动管理栈和堆,其对象存储位置由系统自然分配,程序员不能直接地设置栈或堆。2. 栈的优势是,存取速度比堆要快,仅次于直接位于CPU中的...
  • Java中的引用类型的对象存放在哪里

    千次阅读 2020-06-19 12:04:22
    根据上下文来确定。 根据上下文来确定。...//这个obj随对应的Test对象分配堆里 } 对于方法中的局部变量的引用时存放java运行时数据区的栈中,对于实例变量则是存放java运行时数据区的堆中。 ...
  • 堆中也存放基本数据类型 方法区存放的是类的信息和方法的信息,方法的执行还是栈中进行。
  • String创建的对象存在哪里

    千次阅读 2018-08-31 21:17:34
    直接放测试代码: String a = "asdadas"; String b = "...//堆中 每次创建地址不一样 System.out.println(a.getBytes()); //1 System.out.println(b.getBytes()); //2 St...
  • Java对象的创建及存储位置

    千次阅读 2019-07-13 22:27:17
    对象的创建 对象创建过程(“微观”) ... 当使用new关键字创建对象时,堆上分配足够的存储空间 存储空间清零/null 执行所有出现于字段定义处的初始化动作(非静态初始化) 执行构造器 对...
  • 了解new一个对象具体过程

    千次阅读 2021-04-11 21:38:52
    newnew一个对象的过程发生了什么 new一个对象的过程发生了什么 创建一个对象通常需要两步: 1. 定义构造函数; 2. 通过new来创建对象实例。 当我们使用new新建一个对象的时候,以new foo(…)为例: 1. 一个新的...
  • 如果对象是函数内的非静态局部变量,则对象对象的成员变量保存栈区。 如果对象是全局变量,则对象对象的成员变量保存静态区。 如果对象是函数内的静态局部变量,则对象对象的成员变量保存静态区。 ...
  • Java获取对象引用的地址

    千次阅读 2021-08-06 16:55:59
    测试class: import org.openjdk.jol.vm.VM; public class test { public static void main(String[] args) { String s1 = "abc"; String s2 = new String(s1);... System.out.println(s1.equals(s2));...
  • 对象引用与对象存放的地址和区别

    千次阅读 2020-04-17 00:15:08
    java的学习当中,很多时候并没有能很好分清把对象对象的引用。如果没能很好认识分清这两者的关系,就可能会很难理解一些指针的移动的代码。 JAVA中基本类型变量存储栈中,引用类型的对象存储栈中,对象的...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 424,854
精华内容 169,941
关键字:

对象在哪里