当前位置: 首页 > news >正文

郑州服务设计公司网站广州萝岗区网站建设

郑州服务设计公司网站,广州萝岗区网站建设,国外最大的设计网站,wordpress熊掌号主题面向对象面试题目录 ⛳ 面向对象面试题#x1f69c; 一#xff0c;成员变量#xff0c;局部变量#xff0c;类变量存储在内存的什么地方#xff1f;#x1f43e; 1.1#xff0c;类变量#xff08;静态成员变量#xff09;#x1f4dd; 1.2#xff0c;成员变量⭐ 1.3… 面向对象面试题目录 ⛳ 面向对象面试题 一成员变量局部变量类变量存储在内存的什么地方 1.1类变量静态成员变量 1.2成员变量⭐ 1.3局部变量 二下面变量引用存放在哪里 三HotSpot 方法区的变迁 3.1JDK1.2 ~ JDK6 3.2JDK7☁ 3.3JDK8 3.4方法区的垃圾回收 四为什么调整字符串常量池和静态变量的位置 五为什么用原空间替换永久代 六JDK1.8元空间会产生内存溢出么在什么情况下会产生内存溢出 6.1解析 6.2代码演示 七JVM8的内存结构 八方法区和永久代的区别 8.1**方法区** 8.2**PermGen永久代** 九你知道的几种主要的JVM参数 ⛳ 面向对象面试题 一成员变量局部变量类变量存储在内存的什么地方 1.1类变量静态成员变量 ​ 类变量是用 static 修饰符修饰定义在方法外的变量随着Java进程产生和销毁在Java7及之前把静态变量存放于方法区在Java7时存放在堆中。 1.2成员变量 ​ 成员变量是定义在类中但是没有 static 修饰符修饰的变量随着类的实例产生和销毁是类的实例的一部分 ​ 由于是实例的一部分在类初始化的时候从运行时常量池取出直接引用或者值与初始化的对象一起放入堆中。成员变量可以被类的成员方法访问和修改。如果成员变量是基本类型则存储在堆内存的对象实例中如果成员变量是引用类型则存储在堆内存的对象实例中。 ⭐ 1.3局部变量 ​ 局部变量是定义在类的方法中的变量 ​ 在所在方法被调用时放入虚拟机栈的栈帧中栈顶是正在执行的方法方法执行结束后从虚拟机栈中弹出所以存放在虚拟机栈中。 二下面变量引用存放在哪里 public class StaticObjTest {static class Test{// 静态变量// 一个java.lang.Class类型的对象实例引用了此变量static ObjectHolder staticObj new ObjectHolder();// 实例变量ObjectHolder instanceObj new ObjectHolder();void foo() {// 局部变量ObjectHolder localObj new ObjectHolder()();System.out.println(done);}} private static class ObjectHolder{} public static void main(String[] args) {Test test new StaticObjTest.Test();test.foo();} }以上代码中静态变量staticObj随着 Test 的类型信息存放在在方法区实例变量 instanceObj 随着 Test 的对象实例存放在堆区局部变量 localObj 则是存放在 foo() 方法栈帧的局部变量表中三个变量引用对应的对象实体都是在堆空间 GC回收 地址为 0x004 的实例最容易被回收。地址为 0x003 的实例不容易被回收。地址为 0x001 的实例最不容易被回收会进入到老年代里边。 三HotSpot 方法区的变迁 版本演进细节JDK6及 之前方法区的实现为永久代静态变量存放在永久代中字符串常量池StringTable位于运行时常量池中。JDK7方法区的实现为永久代但已经逐步“去永久代”静态变量、字符串常量池移除保存在堆中JDK8方法区的实现为本地内存的元空间字符串常量池、静态变量仍在堆中 3.1JDK1.2 ~ JDK6 在 JDK1.2 ~ JDK6 的实现中HotSpot 使用永久代持久代实现方法区HotSpot 使用 GC 分代实现方法区带来了很大便利 3.2JDK7 由于 GC 分代技术的影响使之许多优秀的内存调试工具无法在 Oracle HotSpot之上运行必须单独处理 并且 Oracle 同时收购了 BEA 和 Sun 公司同时拥有 JRockit 和 HotSpot在将 JRockit 许多优秀特性移植到 HotSpot 时由于 GC 分代技术遇到了种种困难所以从 JDK8 开始 Oracle HotSpot 开始移除永久代。 JDK7中符号表被移动到 Native Heap中 字符串常量和类引用被移动到 Java NON_HEAP中。 Native Heap 是程序运行时动态的向操作系统申请的内存JVM Heap 是在 Native Heap 划分出一块区域作为JVM Heap。 Java NON_HEAP : 在Java中内存分为两个主要部分堆内存Heap和非堆内存Non-Heap。 堆内存用于存储对象实例和数组等动态分配的数据。它是Java程序运行时的主要内存区域由垃圾回收器管理。通过调整堆内存的大小可以影响Java程序的性能和内存使用情况。 非堆内存是指除了堆内存之外的内存区域主要包括以下几个部分 方法区Method Area也称为永久代Permanent Generation在较早的JDK版本中使用。它用于存储类的元数据如类的结构信息、常量池、静态变量等和方法字节码等信息。在JDK 8及以后的版本中永久代被元空间Metaspace取代。常量池Constant Pool常量池是方法区的一部分用于存储字符串常量、符号引用等。在JDK 7及以后的版本中常量池被移至堆内存的一部分称为字符串常量池String Pool。直接内存Direct Memory直接内存是通过java.nio包提供的一种与操作系统直接交互的内存分配方式。它不受Java堆大小的限制可以用于高效地进行I/O操作。直接内存的分配和释放由Java虚拟机管理但实际的内存空间是在操作系统层面上分配的。 非堆内存的大小和使用情况通常由Java虚拟机的参数进行配置例如-XX:MaxPermSize用于设置永久代的最大大小和-XX:MaxDirectMemorySize用于设置直接内存的最大大小等。 注根据虚拟机版本的更迭名词可能会发生变化。 ☁ 3.3JDK8 在 JDK8 中永久代已完全被元空间(Meatspace)所取代。 3.4方法区的垃圾回收 方法区的垃圾回收主要分为两个部分常量池中废弃的常量和不再使用的类。 在JDK1.7及之前HotSpot虚拟机将Java信息常量池静态变量即使编译后的代码JIT等数据存储在Perm永久代里对于其它虚拟机如BEA JRockit、IBM J9等是不存在永久带概念的类的元数据和静态变量在类加载的时候被分配到Perm里当常量池回收或者类被卸载时垃圾收集器会回收这部分内存但效果不太理想。 JDK1.8中则把永久代给完全删除了取而代之的是Meta Space将类元数据放到了本地内存中将常量池和静态变量放到了Java堆里HotSpot VM将会为类的元数据明确地分配与释放本地内存在这种架构下类元数据就突破了-XX:MaxPermSize的限制所以此配置已经失效了现在可以使用更多的本地内存。这样一定程度上解决了原来在运行时生成大量的类从而经常 Full GC 的问题 — 如运行时使用反射代理等。 方法区的概念是Java内存模型JMM提出的规范而永久代Perm是HotSpot对这种规范的实现。 为什么JDK1.8要把方法区从JVM里永久代移到直接内存元空间 字符串存在永久代中容易出现性能问题和内存溢出。 类及方法的信等比较难确定其大小因此对于永久代的大小指定比较困难。 永久代会为GC带来不必要的复杂度并且回收效率偏低。 Java虚拟机JVM运行时常量池是一种用于存储编译期生成的各种字面量和符号引用的表。他是Class文件结构的一部分位于每个类或接口的常量池区域。在运行Java程序是JVM会使用这些常量池中的信息。 JVM运行时常量池可以包含以下类型的内容 字面量Literal这包括整数、浮点数、字符和字符串等常量值。符号引用Symbolic References这是一种编译时的引用包括类和接口的全限定名、字段的名称和描述符、方法的名称和描述符等。 常量池中的数据可以被直接使用或者通过符号引用在运行时解析。它的主要目的是节省内存空间和提高执行性能因为常量池中的数据可以被多个地方引用而不需要每次都复制一份。 四为什么调整字符串常量池和静态变量的位置 JDK7中将字符串常量池放到了堆空间中因为永久代的回收效率很低在Full GC时才会触发而Full GC在老年代的空间不足、永久代不足时才会触发这就导致字符串常量池回收效率不高 而我们开发中会有大量的字符串被创建回收效率低会导致永久代内存不足。 将字符串常量池放到堆里能及时回收内存。 五为什么用原空间替换永久代 为永久代设置最大空间大小是难以确定的。 在某些场景下如果动态加载类过多容易产生Perm区的OOM比如某个实际Web工程中因为功能点比较多在运行过程中要不断动态加载很多类经常出现致命错误而元空间和永久代之间最大的区别在于元空间并不在虚拟机中而是使用本地内存因此默认情况下元空间的最大大小仅受本地内存限制。对永久代进行调优是很困难的。 六JDK1.8元空间会产生内存溢出么在什么情况下会产生内存溢出 6.1解析 Java8 及以后的版本使用Metaspace来代替永久代Metaspace是方法区在HotSpot中的实现它与永久代最大区别在于Metaspace并不在虚拟机内存中而是使用本地内存也就是在JDK8中classe meta data(the virtual machines internal presentation of Java class),被存储在叫做Metaspace的native memory。 永久代java 8 后被元空间Metaspace取代了存放了以下信息 虚拟机加载的类信息常量池即时编译后的代码 **内存溢出的原因**加载到内存中的 class 数量太多或者体积太大。 **解决办法**增加 Metaspace 的大小 -XX:MaxMetaspaceSize512m6.2代码演示 模拟Metaspace空间溢出我们不断生成类往元空间灌类占据的空间是会超过Metaspace指定的空间大小的 查看元空间大小 java -XX:PrintFlagsInitial官方标准 1字节Byte)8字位8个二进制数 1字位(bit)1个二进制数 1B8b 1KB1024B 1MB1024KB 1GB1024MB 通常情况下把B称为字节、b称为字位、KB称为千字节、MB称为兆字节、GB称为吉字节。 默认是大约20.80M这里设置10m方便演示效果 -XX:MetaspaceSize10m -XX:MaxMetaspaceSize10m测试代码(必须是一个spring boot工程)如下 public class MetaspaceDemo {static class OOM{}public static void main(String[] args) {int i 0;//模拟计数多少次以后发生异常try {while (true){i;Enhancer enhancer new Enhancer();enhancer.setSuperclass(OOM.class);enhancer.setUseCache(false);enhancer.setCallback(new MethodInterceptor() {Overridepublic Object intercept(Object o, Method method, Object[] objects,MethodProxy methodProxy) throws Throwable {return methodProxy.invokeSuper(o,args);}});enhancer.create();}} catch (Throwable e) {System.out.println(多少次后发生异常i);e.printStackTrace();}} }cglib默认开启了UserCache生成的代理类都会复用原先产生在缓存中的类所以至始至终都只有一个代理类所以不会产生内存溢出。手动关闭它enhancer.setUseCache(false); 七JVM8的内存结构 程序计数器Program Counter Register 程序计数器就是当前线程所执行的字节码的行号指示器通过改变计数器的值来选取下一行指令通过他来实现跳转、循环、恢复线程等功能。 在任何时刻一个处理器内核只能运行一个线程多线程是通过线程轮流切换分配时间来完成的这就需要有一个标志来记住每个线程执行到了哪里这里便需要到了程序计数器。程序计数器是线程私有的每个线程都已自己的程序计数器。 虚拟机栈JVM Stacks 虚拟机栈是线程私有的随线程生灭。虚拟机栈描述的是线程中的方法的内存模型每个方法被执行的时候都会在虚拟机栈中同步创建一个栈帧stack frame**方法被执行时入栈执行完后出栈**每个栈帧的包含如下的内容 局部变量表: 局部变量表中存储着方法里的java基本数据类型byte/boolean/char/int/long/double/float/short以及对象的引用注这里的基本数据类型 指的是方法内的局部变量操作数栈动态连接方法返回地址 虚拟机栈可能会抛出两种异常 如果线程请求的栈深度大于虚拟机所规定的栈深度则会抛出StackOverFlowError即栈溢出如果虚拟机的栈容量可以动态扩展那么当虚拟机栈申请不到内存时会抛出OutOfMemoryError即OOM内存溢出 产生StackOverFlowError的原因是 无限递归循环调用最常见。执行了大量方法导致线程栈空间耗尽。方法内声明了海量的局部变量。 本地方法栈Native Method Stacks 本地方法栈与虚拟机栈的作用是相似的,都会抛出OutOfMemoryError和StackOverFlowError都是线 程私有的主要的区别在于 虚拟机栈执行的是java方法本地方法栈执行的是native方法 Java堆Java Heap java堆是JVM内存中最大的一块由所有线程共享, 是由垃圾收集器管理的内存区域主要存放对象实例当然由于java虚拟机的发展堆中也多了许多东西现在主要有 对象实例 类初始化生成的对象基本数据类型的数组也是对象实例 字符串常量池 字符串常量池原本存放于方法区从jdk7开始放置于堆中。字符串常量池存储的是string对象的直接引用而不是直接存放的对象是一张string table 静态变量 静态变量是有static修饰的变量jdk7时从方法区迁移至堆中 线程分配缓冲区Thread Local Allocation Buffer 线程私有但是不影响java堆的共性增加线程分配缓冲区是为了提升对象分配时的效率 java堆既可以是固定大小的也可以是可扩展的通过参数-Xmx和-Xms设定如果堆无法扩展或者无法分配内存时也会报OOM。 方法区(Method Area) 它用于存储已被虚拟机加载的类型信息、常量、静态变量、即时编译器编译后的代码缓存等。 1类型信息 对每个加载的 类型 类class、接口interface、枚举enum、注解annotationJVM必须在方法区中存储以下类型信息 这个类型的完整有效名称全名包名.类名这个类型直接父类的完整有效名对于interface或是java.lang. Object都没有父类这个类型的修饰符 public, abstract,final的某个子集这个类型实现接口的一个有序列表。 2 域Field信息 JVM必须在方法区中保存类型的所有域的相关信息以及**域的声明顺序。**域的相关信息包括如下内容 域名称域类型域修饰符publicprivateprotectedstaticfinal volatiletransient的某个子集 3 方法Method信息 JVM必须在方法区中保存类型的所有方法的相关信息以及方法的声明顺序。方法的相关信息包括 方法名称方法的返回类型或void方法参数的数量和类型按顺序方法的修饰符publicprivateprotectedstaticfinalsynchronizednativeabstract的一个子集方法的字节码bytecodes、操作数栈、局部变量表及大小 abstract和native方法除外异常表abstract和 native方法除外每个异常处理的开始位置、结束位置、代码处理在程序计数器中的偏移地址、被捕获的异常类的常量池索引 4静态变量non-final的 静态变量和类关联在一起随着类的加载而加载它们成为类数据在逻辑上的一部分。类变量被类的所有实例共享即使没有类实例时你也可以访问它。 补充说明被声明为final的静态变量的处理方法则不同被static和final修饰的变量也称为全局变量每个全局常量在编译的时候就会被赋值了。 public class Order {public static int num 10;public static final int COUNT 20; }通过javap命令反编译后的class文件 5运行时常量池 理解运行时常量池需要了解字节码文件ClassFile中的常量池方法区内部包含运行时常量池字节码文件内部包含了常量池。 常量池一个有效的字节码文件中除了包含类的版本信息、字段、方法以及接口等描述信息外还包含一项信息那就是常量池 Constant Pool Table包括各种字面量数量值和字符串值和对类型、域和方法的符号引用。常量池可以看做是一张表虚拟机指令根据这张常量表找到要执行的字面量、类名、方法名、参数类型等。 运行时常量池 运行时常量池Runtime Constant pool是方法区的一部分。常量池Constant Pool Table是class文件的一部分用于存放编译期生成的各种字面量与符号引用这部分内容将在类加载后存放到方法区的运行时常量池中。在加载类和接口到虚拟机后就会创建对应的运行时常量池。JVM为每个已加载的类型类或接口都维护一个运行时常量池池中的数据项像数组项一样是通过索引访问的。运行时常量池中包含多种不同的常量包括编译期就已经明确的数值字面量也包括到运行期解析后才能够获得的方法或者字段引用。此时不再是常量池中的符号地址了会转换为真实地址。运行时常量池相对于Class文件中的常量池的另一重要特征是具备动态性。比如String.intern()方法会动态地向池中增加内容运行时常量池类似于传统编程语言中的符号表symbol table但是它所包含的数据比符号表要更加丰富。如果构造类或接口的运行时常量池时所需的内存空间超过了方法区所能提供的最大值则JVM会抛出OutOfMemoryError异常。 直接内存(Direct Memory) jdk1.4中加入了NIO(New Input/Putput)类引入了一种基于通道(channel)与缓冲区(buffer)的新IO方式它可以使用native函数直接分配堆外内存然后通过存储在java堆中的DirectByteBuffer对象作为这块内存的引用进行操作这样可以在一些场景下大大提高IO性能避免了在java堆和native堆来回复制数据。 java 的 NIO 库允许 java 程序使用直接内存。直接内存是在 java 堆外的、直接向系统申请的内存空间。通常访问直接内存的速度会优于 java 堆。因此出于性能的考虑读写频繁的场合可能会考虑使用直接内存。由于直接内存在 java 堆外因此它的大小不会直接受限于 Xmx 虚拟机参数指定的最大堆大小但是系统内存是有限的 java 堆和直接内存的总和依然受限于操作系统能给出的最大内存。直接内存位于本地内存不属于JVM内存不受GC管理但是也会在物理内存耗尽的时候报OOM。 注意direct buffer不受GC影响但是direct buffer归属的JAVA对象是在堆上且能够被GC回收的一旦它被回收JVM将释放direct buffer的堆外空间 直接内存(Direct Memory)的特点 直接内存并非 JVMS 定义的标准 Java 运行时内存。JDK1.4 加入了新的 NIO 机制目的是防止 Java 堆 和 Native 堆之间往复的数据复制带来的性能损耗此后 NIO 可以使用 Native 的方式直接在 Native 堆分配内存。直接内存区域是全局共享的内存区域。直接内存区域可以进行自动内存管理(GC)但机制并不完善。本机的 Native 堆(直接内存) 不受 JVM 堆内存大小限制。可能出现 OutOfMemoryError 异常。 八方法区和永久代的区别 8.1方法区 ​ 方法区属于JVM规范的内容JVM规范中方法区主要用于存储类的信息、常量池、方法数据、方法代码等。 ​ 方法区 是 JVM 的规范所有虚拟机 必须遵守的。常见的JVM 虚拟机 Hotspot 、 JRockitOracle、J9IBM 8.2PermGen永久代 PermGen 就是 PermGen space 全称是 Permanent Generation space 是指内存的永久保存区域。 这块内存主要是被JVM存放Class和Meta信息的 Class 在被 Loader 时就会被放到 PermGen space中。 ​ 绝大部分 Java 程序员应该都见过 java.lang.OutOfMemoryError: PermGen space 这个异常。 这里的 PermGen space 其实指的就是 方法区 。 PermGen space 则是 HotSpot 虚拟机 基于 JVM 规范对 方法区 的一个落地实现PermGen space 是 HotSpot 虚拟机有而如 JRockitOracle、J9IBM 虚拟机有 方法区 但是就没有 PermGen space。 强调 只有 HotSpot 才有 PermGen space。 ​ PermGen space 则是 HotSpot 虚拟机 基于 JVM 规范对 方法区 的一个落地实现PermGen space 是 JDK7及之前 HotSpot 虚拟机 对 方法区 的一个落地实现。HotSpot jdk1.6 的 PermGen space 如下 HotSpot 也有去永久代的趋势在 JDK 1.7 中 HotSpot 已经开始了“去永久化”把原本放在永久代的字符串常量池移出。 HotSpot 1.7 永久代主要存放常量、类信息、静态变量等数据与垃圾回收关系不大新生代和老年代是垃圾回收的主要区域。 永久代 在JDK8被移除, JDK1.8方法区 叫做 元空间 Metaspace元空间是 JDK8及之后 HotSpot 虚拟机 对 方法区 的新的实现。 九你知道的几种主要的JVM参数 1思路 可以说一下堆栈配置相关的垃圾收集器相关的还有一下辅助信息相关的。 2参考答案 1堆栈配置相关 -Xmx3550m 最大堆大小为3550m。 -Xms3550m 设置初始堆大小为3550m。 -Xmn2g 设置年轻代大小为2g。 -Xss128k 每个线程的堆栈大小为128k。 -XX:MaxPermSize 设置持久代大小为16m -XX:NewRatio4: **设置年轻代包括Eden和两个Survivor区与年老代的比值除去持久代比例为1:4 **-XX:SurvivorRatio4 设置年轻代中Eden区与Survivor区的大小比值。设置为4则两个Survivor区与一个Eden区的比值为2:4一个Survivor区占整个年轻代的1/6 -XX:MaxTenuringThreshold0 **设置垃圾最大年龄。如果设置为0的话则年轻代对象不经过Survivor区直接进入年老代。 **2垃圾收集器相关 -XX:UseParallelGC 选择垃圾收集器为并行收集器。 –XX:UseParNewGC指定使用 ParNew Serial Old 垃圾回收器组合 -XX:ParallelGCThreads20 配置并行收集器的线程数 -XX:UseConcMarkSweepGC指定使用 CMS Serial Old 垃圾回收器组合 -XX:CMSFullGCsBeforeCompaction**由于并发收集器不对内存空间进行压缩、整理所以运行一段时间以后会产生“碎片”使得运行效率降低。此值设置运行多少次GC以后对内存空间进行压缩、整理。** -XX:UseCMSCompactAtFullCollection **打开对年老代的压缩。可能会影响性能但是可以消除碎 **片 3辅助信息相关 -XX:PrintGC 输出形式: [GC 118250K-113543K(130112K), 0.0094143 secs] [Full GC 121376K-10414K(130112K), 0.0650971 secs]-XX:PrintGCDetails 输出形式: [GC [DefNew: 8614K-781K(9088K), 0.0123035 secs] 118250K-113543K(130112K), 0.0124633 secs] [GC [DefNew: 8614K-8614K(9088K), 0.0000665 secs][Tenured: 112761K-10414K(121024K), 0.0433488 secs] 121376K-10414K(130112K), 0.0436268 secs
http://www.zqtcl.cn/news/660060/

相关文章:

  • 做国外网站什么好网站快速优化排名排名
  • 如东做网站专注高密网站建设
  • dw网页设计作品简单宁波seo排名方案
  • 网站做微信接口吗小说网站首页模板
  • 网站正在建设中html个人站长做网站需要多少钱
  • 做推广便宜的网站有哪些数据网站建设哪家好
  • 中介网站制度建设wordpress genesis
  • 广东贸易网站开发用数据库做学校网站论文
  • 关于省钱的网站名字东莞哪些网络公司做网站比较好
  • net网站建设多少前MAC怎么做网站
  • 创建网站流程图国内高清图片素材网站推荐
  • 淄博住房和城乡建设局网站建设外贸网站哪家好
  • dede网站地图路径密云区免费网站建设
  • 男女做那事是什 网站软文网
  • 安徽建海建设工程有限公司网站活动推广宣传方案
  • 镇江市建设审图网站关键词优化过程
  • 广州个人网站备案要多久手机软件界面设计
  • 网站建设成都公司哪家好wordpress悬浮代码
  • 制作网站服务公司wordpress文章添加关注公众号
  • 陶瓷企业 瓷砖地板公司网站建设视频解析wordpress
  • 城乡建设厅网站首页wordpress模板汉化教程视频
  • 网站建设怎么设置渐变色手机网站开发服务商
  • 网站备案用座机租用南宁网站建设优化排名
  • 网页制作与网站建设实战大全读后感霞浦建站公司
  • 网站运营与网络推广方案搜索引擎关键字排名优化
  • 前端角度实现网站首页加载慢优化王业美三个字组成的子
  • 阜阳网站是用idea做html网站
  • 商业网站可以选择.org域名吗seo是东莞企业网站排seo
  • 做百度手机网站关键词排名哪个通讯公司的网络好
  • 网站后期维修问题qq网站建设