jvm 代码段、数据段、堆、栈

1.引用 万物为铜的 文章:https://www.cnblogs.com/lipeineng/p/8358601.html

https://blog.csdn.net/kevlnbb/article/details/94396283

                           jvm 代码段、数据段、堆、栈

代码段:通常是指用来存放程序执行代码的一块内存区域。这部分区域的大小在程序运行前就已经确定,并且内存区域通常属于只读, 某些架构也允许代码段为可写,即允许修改程序。在代码段中,也有可能包含一些只读的常数变量,例如字符串常量等。

BSS:通常是指用来存放程序中未初始化的全局变量和静态变量的一块内存区域。特点是:可读写的,在程序执行之前BSS段会自动清0。所以,未初始的全局变量在程序执行之前已经成0了。

数据段:通常是指用来存放程序中已初始化的全局变量的一块内存区域。数据段属于静态内存分配。

堆:C语言堆:堆是用于存放进程运行中被动态分配的内存段,它的大小并不固定,可动态扩张或缩减。当进程调用malloc等函数分配内存时,新分配的内存就被动态添加到堆上(堆被扩张);当利用free等函数释放内存时,被释放的内存从堆中被剔除(堆被缩减)

堆:jvm堆:对于优先级队列增删操作O(log(n))的树形数据结构。用来存放动态产生的数据,比如new出来的对象和Class对象本体。注意创建出来的对象只包含属于各自的成员变量,并不包括成员方法。因为同一个类拥有各自的成员变量,存储在堆中的不同位置,但是同一个类不同实例的他们共享该类的方法,并不是每创建一个对象就把成员方法复制一次。

栈:保存局部变量的值:包括1.基本数据类型的值,非对象类型。2.保存类的实例,即堆区对象的引用(指针)。3.保存加载方法时的帧

jvm 代码段、数据段、堆、栈

2.java 程序加载过程

https://blog.csdn.net/dufufd/article/details/80537638

https://blog.csdn.net/Searchin_R/article/details/84591735

理解Class对象和实例对象

原文链接:https://blog.csdn.net/Searchin_R/article/details/84591735

Class对象到底是什么呢?今天我们就来深入了解一下它。

1.RTTI的概念
RTTI(Run-Time Type Identification),即运行时类型识别,这个词一直是 C++ 中的概念,至于Java中出现RRTI的说法则是源于《Thinking in Java》一书,其作用是在运行时识别一个对象的类型和类的信息。

RTTI分两种:传统的”RTTI”与反射机制。

对于传统的“RTTI”,它假定我们在编译期已知道了所有类型(在没有反射机制创建和使用类对象时,一般都是编译期已确定其类型,如new对象时该类必须已定义好)。

另外一种是反射机制,它允许我们在运行时发现和使用类型的信息。在Java中用来表示运行时类型信息的对应类就是Class类。


2.Class类
Class类也是一个实实在在的类,存在于JDK的java.lang包中,其部分源码如下:

public final class Class<T> implements java.io.Serializable,GenericDeclaration,Type, AnnotatedElement {
    private static final int ANNOTATION= 0x00002000;
    private static final int ENUM      = 0x00004000;
    private static final int SYNTHETIC = 0x00001000;
 
    private static native void registerNatives();
    static {
        registerNatives();
    }
 
    /*
     * Private constructor. Only the Java Virtual Machine creates Class objects.(私有构造,只能由JVM创建该类)
     * This constructor is not used and prevents the default constructor being
     * generated.
     */
    private Class(ClassLoader loader) {
        // Initialize final field for classLoader.  The initialization value of non-null
        // prevents future JIT optimizations from assuming this final field is null.
        classLoader = loader;
    }
对象是类的实例化,那么既然Class类是真实存在,那么自然也可以被实例化。而Class的创建的实例就是Class对象。

3.Class对象
上文说到Class类被创建后的对象就是Class对象,这里需要注意,Class对象表示的是自己手动编写类的类型信息。

这是什么意思呢?比如创建一个Searchin类,那么,JVM就会创建一个Searchin对应Class类的Class对象,该Class对象则保存了Searchin类相关的类型信息。

实际上在Java中每个类都有且只有一个Class对象。

每当我们编写并且编译一个新创建的类就会产生一个对应Class对象并且这个Class对象会被保存在同名.class文件里。说到.class文件,大家可能很熟悉,因为Java程序编译之后就会有.class文件。事实上,编译后的字节码文件保存的就是Class对象。

那为什么需要这样一个Class对象呢?

是这样的,当我们new一个新对象或者引用静态成员变量时,Java虚拟机(JVM)中的类加载器子系统会将对应Class对象加载到JVM中,然后JVM再根据这个类型信息相关的Class对象创建我们需要实例对象或者提供静态变量的引用值。也就是说,Class对象对于类的实例化具有非常重要的意义。没它就没法new新对象和引用静态成员变量。

这里需要再次重点提醒一下,上文说到“Java中每个类只有一个Class对象”,这句话是什么意思呢?

对于手动编写的每个Class类,无论创建多少个实例对象,在JVM中都只有一个Class对象,即在内存中每个类有且只有一个相对应的Class对象。

这里给大家画个简单的图,方便大家理解。

                                       jvm 代码段、数据段、堆、栈

4.总结
通过上文所提及知识,我们可以得出以下几点信息:

Class类也是类的一种,与class关键字是不一样的。
手动编写的类被编译后会产生一个Class对象,其表示的是创建的类的类型信息,该Class对象保存在同名.class的文件中(即编译后得到的字节码文件)。(会被加载到内存)
每个通过关键字class标识的类,在内存中有且只有一个与之对应的Class对象来描述其类型信息,无论创建多少个实例对象,其依据的都是用一个Class对象。
Class类只存私有构造函数,因此对应Class对象只能有JVM创建和加载
Class类的对象的作用是运行时提供或获得某个对象的类型信息,这点对于反射技术很重要。