当前位置: 首页> 娱乐> 八卦 > 网络营销和网上销售的区别_山东高级网站建设_网上销售推广方案_南宁关键词优化服务

网络营销和网上销售的区别_山东高级网站建设_网上销售推广方案_南宁关键词优化服务

时间:2025/7/15 2:26:57来源:https://blog.csdn.net/qq_73574147/article/details/147253153 浏览次数:0次
网络营销和网上销售的区别_山东高级网站建设_网上销售推广方案_南宁关键词优化服务

运行时数据区

Java 虚拟机在运行 Java 程序过程中管理的内存区域称之为运行时数据区,运行时数据区负责管理 JVM 使用到的内存,例如创建对象和销毁对象。

image-20240612192812789

程序计数器

程序计数器又叫 PC 寄存器,每个线程都会通过程序计数器记录当前要执行的字节码指令的地址。

image-20240612193244200

程序计数器可以控制程序指令的进行,实现分支、跳转、异常等逻辑。

image-20240612193931200

在多线程执行情况下,Java 虚拟机需要通过程序计数器记录 CPU 切换前解释执行到哪一句指令并继续解释运行。

image-20240612194353434

Java 虚拟机栈采用栈这种数据结果来管理调用中的基本数据,每一个方法的调用使用了一个栈帧(Stack Frame)进行保存。

image-20240616094445545

编写如下程序,通过 IDEA断点的方式可以查看到当前线程栈中的内容:

public static void main(String[] args) {System.out.println("程序员的一天..");oneDay();
}public static void oneDay() {eat();
}
public static void code() {System.out.println("编码");
}
public static void sleep() {System.out.println("睡觉");code();
}
public static void eat() {System.out.println("吃饭");sleep();
}

在 IDEA 调试窗口的左下角可以看到栈中的信息,点击即可跳转到该栈帧所执行的代码位置。

image-20240616094026791

Java 虚拟机栈是随着线程的生命周期而变化的,即随着线程的创建而创建,随着线程的销毁而被回收。由于方法可能会在不同的线程中执行,所以每个线程都会有自己的虚拟机栈。

局部变量表

其作用是在方法的执行过程中存放所有的局部变量。当代码编译成字节码文件时就可以确定局部变量表的内容。

如下图,其中 Nr 代表的是该变量的编号,起始 PC 是指该变量被初始化后的下一条字节码指令的序号(即可以访问该变量的时机),长度是指该变量的有效访问字节码指令的范围(例如变量i在1号指令被初始化完成,在2号指令开始可以被访问使用,有效访问范围是2,3,4号指令,即长度为3)

image-20240616095103688

栈帧中的局部变量是一个数组,数组中的每一个位置称之为槽(slot),除了 long 和 double 类型占用两个槽,其余类型占用一个槽。

image-20240616095800932

若方法为为非静态方法的实例方法,则其中序列为0的位置是存放this,指当前调用方法的对象,运行时会在内存中存放实例对象的地址。

image-20240616100845212

局部变量表中保存内容的优先级为:this 对象> 方法参数 > 声明的局部变量

image-20240616101016117

为了节省空间,局部变量表中的槽是可以进行复用的,一旦某个局部变量不再生效,则当前槽就可以再次被使用。

操作数栈

操作数栈是栈帧中虚拟机在执行指令过程中用来存放中间数据的一块区域。其是一种栈式的数据结构,若一条指令将一个值压入操作数栈,则后面的指令可以弹出并使用该值。同时可以在编译期间确定操作数栈的最大深度,从而在执行时正确的分配内存大小。

image-20240616103114916

帧数据

帧数据中包含动态链接、方法出口、异常表的引用。

当前类的字节码指令引用了其他类的属性或方法时,则需要将符号引用(编号)转换为对应的运行时常量池中的内存地址。动态链接则是保存了编号到运行时常量池的内存地址的映射关系。

方法出口指方法在正确或异常结束时,当前栈帧会被弹出,同时程序计数器应该指向上一个栈帧中的下一条指令的地址。所以在当前栈帧中,需要存储此方法出口的地址。

而异常表存放的是代码中异常的处理信息,包含了异常捕获的生效范围以及异常发生后跳转到的字节码指令位置。

image-20240616110100271

Java 虚拟机栈若栈帧过多,占用内存超过占内存可以分配的最大大小则会出现内存溢出的现象,抛出 StackOverflowError 的错误。

为了证明这个结论,可以将上面的代码进行一个小小的改动,在 code 方法中添加一个 eat 方法的调用。

public static void main(String[] args) {System.out.println("程序员的一天..");oneDay();
}public static void oneDay() {eat();
}
public static void code() {System.out.println("编码");eat();
}
public static void sleep() {System.out.println("睡觉");code();
}
public static void eat() {System.out.println("吃饭");sleep();
}

这样就形成了一个调用循环,执行时则会看到抛出StackOverflowError异常

image-20240616110709431

若不指定栈的大小,JVM 会创建一个具有默认大小的栈,而这个大小则取决于操作系统和计算机的体系结构。

image-20240616110947443

设置栈大小

可以使用虚拟机参数-Xss进行修改 Java 虚拟机栈的大小。单位默认为字节(默认必须是1024的倍数),其余的单位有k、m、g(大小写都可以)

-Xss2048
-Xss3K
-Xss2m

与 -Xss 类似,也可以使用 -XX:ThreadStackSize 调整标志来配置堆栈大小。

-XX:ThreadStackSize=1024

当局部变量过多,操作数栈深度过大时也会影响到栈内存的大小。Windows 64位的机器中 JDK 8测试的栈最小值为 180K,最大值为 1024M。在一般情况下,工作中即便使用了递归进行操作,栈的深度最多也只能到达

本地方法栈

Java虚拟机栈存储了Java方法调用时的栈帧,而本地方法栈存储的是native本地方法的栈帧。

在 Hotspot 虚拟机中,Java虚拟机栈和本地方法栈实现上使用了同一个栈空间。

本地方法栈会在栈内存上生成一个栈帧,临时保存方法的参数同时方便出现异常时也把本地方法的栈信息打印出来。

Java 程序中创建出来的对象都存在于堆上,所以堆内存是空间最大的一块内存区域。在栈上的局部变量表中,可以存放堆上对象的引用,静态变量也可以存放堆对象的引用,通过静态变量便可以实现对象在线程之间的共享。

当然,堆内存也是有上限的,如果一直创建新的对象并不及时清理不用的类,则当堆中放入对象达到上限时,就会抛出java.lang.OutOfMemoryError: Java heap space

堆中会有usedtotalmax三个值,其中分别代表的是当前已经使用的堆内存、Java 虚拟机已经分配的可用堆内存、Java 虚拟机可以分配的最大堆内存。

若不设置任何的虚拟机参数,则 max 默认是系统内存的四分之一,total 默认是系统内存的六十四分之一。当然,在实际的生产开发中需要手动设置total和max的值。

可以使用-Xmx(max最大值)和-Xms(初始的total)虚拟机参数修改堆的大小。要求Xmx必须大于2MB,Xms必须大于1MB。单位是字节(默认是 1024 的倍数),或k(K/KB)、m(M/MB)、g(G/GB)

-Xmx1024m -Xms1024m

Java服务端程序开发时,建议将-Xmx和-Xms设置为相同的值,这样在程序启动之后可使用的总内存就是最大内存,而无需向java虚拟机再次申请,减少了申请并分配内存时间上的开销,同时也不会出现内存过剩之后堆收缩的情况。

方法区

方法区存放基础信息的文职,是线程共享的,其中主要包含了:类的元信息运行时常量池字符串常量池

方法区存储每个类的基本信息,一般称之为InstanceKlass对象,该过程在类的加载阶段完成。

方法区除了存储类的元信息之外,还存放了运行时常量池。常量池中存放的是字节码中的常量池内容。

字节码文件中通过编号查表的方式找到常量,这种常量池称为静态常量池。当常量池加载到内存中之后,可以通过内存地址快速的定位到常量池中的内容,这种常量池称为运行时常量池。

image-20240616152151181

方法区是《Java虚拟机规范》中设计的虚拟概念,每款Java虚拟机在实现上都各不相同。Hotspot是这样设计的:

  • JDK7及之前的版本将方法区存放在堆区域中的永久代空间,堆的大小由虚拟机参数(-XX:MaxPermSize=值)来控制。
    image-20240616152356852

    jdk7及其之前版本可以通过Arthas查看 ps_perm_gen 属性
    image-20240616152806654

  • JDK8及之后的版本将方法区存放在元空间中,元空间位于操作系统维护的直接内存中,默认情况下只要不超过操作系统承受的上限,可以一直分配。也可以通过设置虚拟机参数(-XX:MaxMetaspaceSize=值)限制元空间最大大小(一般建议为256M,即30多万个类加载)。
    image-20240616152418850

    JDK 8之后可以通过查看 metaspace 属性
    image-20240616152921106

字符串常量池存储在代码中定义的常量字符串内容。

字符串常量池发展进程:

image-20240616162238836

直接内存

直接内存并不属于 Java 运行时内存区域,在 JDK 1.4 中引入 NIO 机制,使用直接内存解决了下面的两个问题:

  1. 当 Java 堆中的对象不再使用而回收时,回收的时候会影响对象的创建和使用。
  2. 使用如读文件等IO操作时需要先将文件读入直接内存(缓冲区)中,然后再将数据复制到 Java 堆中。
    image-20240617115507227

而现在可以直接存放入直接内存即可,同时 Java 堆上维护直接内存的引用,减少了数据复制的开销。

image-20240617115617206

如果需要手动调整直接内存的大小,则可以使用 Java 虚拟机参数-XX:MaxDirectMemorySize=大小默认情况下,JVM 将自动选择最大分配的大小。

-XX:MaxDirectMemorySize=1m # 直接内存大小设置为1MB
关键字:网络营销和网上销售的区别_山东高级网站建设_网上销售推广方案_南宁关键词优化服务

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: