`
m635674608
  • 浏览: 4937222 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

jvm 初始化

阅读更多
package test;

public class A {
	private static A a = new A();

	private B b = B.getInstance();

	private A() {

	}

	public static A getInstance() {
		System.out.println("A被调用");
		return a;
	}

	public void test() {
		System.out.println(b);
	}
}

 

package test;

public class B {
	private static B b = new B();

	private A a = A.getInstance();

	private B() {

	}

	public static B getInstance() {
		System.out.println("B被调用");
		return b;
	}

	public void test() {
		System.out.println(a);
	}
}

 

package test;


/**
 * 面先说一下环境,比如现在有两个类,A和B,两个类都是单例类,这个时候如果A有个B的实例变量,B有个A的实例变量,
 * 会发生什么情况呢?开始我以为会出现栈溢出。但是让我迷惑的是,居然没问题。只是其中一个类的 实例变量会是NULL。
 * 下面看代码。 

 * @author zhang_zengmin
 *
 */
public class Test {

	/**
	 * @param args
	 */
	public static void main(String[] args) {

		B b = B.getInstance();
		b.test();
		System.out.println("==========");
		A a = A.getInstance();
		a.test();

		// A a = A.getInstance();
		// a.test();
		// System.out.println("==========");
		// B b = B.getInstance();
		// b.test();
		// System.out.println("==========");
		/**
		 * 1.类Test的main()方法的B.getInstance()生成的invokestatic指令触发了类B的初始化 
			2.执行类B的<clinit>方法的过程中,显式调用了B自己的<init>方法(static b = new B()) 
			3.B的<init>方法中,调用A.getInstance()生成的invokestatic指令触发了A的初始化(private A a = A.getInstance()) 
			4.执行A的<clinit>方法的过程中调用了A自己的<init>方法(static a = new A()) 
			5.类A的<init>方法中需要调用B.getInstance(),但是虚拟机中一个类(<class,classloader>为一个类)只会初始化一次,因此不会再触发B的初始化,既不会再执行B.<clinit>方法。 
			6.那由a.<init>触发的B.getInstance()被执行,输出第一行“B被调用”,B.getInstance()方法结束。虽然这时候B的初始化阶段尚未结束,但是解析阶段已经完成,所以getInstance()方法可以被正确执行,但这时候静态字段static B b仍然为null(注意,b.<init>方法还没完呢),所以这个B.getInstance()方法返回值为null,所以A.b为null。 
			7.A.<clinit>方法结束,第3步的invokestatic指令正式执行,即A.getInstance()被执行,输出第二行“A被调用”,返回A的实例,这时候B.a不为null了。 
			8.B.<clinit>方法结束,第1步的invokestatic指令正式执行,即B.getInstance()被执行,输出第三行“B被调用” 
			9.B.test()方法被执行,输出B.a的toString()方法结果,即第四行“A@35ce36”。 
			10.A.getInstance()方法被执行,输出第五行“A被调用”。 
			11.A.test()方法被执行,输出null,即A.b的值。 
		 */
	}

}

 

分享到:
评论

相关推荐

    Java虚拟机JVM类加载初始化

    当一个类被加载、连接、初始化后,它的生命周期就开始了,当代表该类的Class对象不再被引用、即已经不可触及的时候,Class对象的生命周期结束。那么该类的方法区内的数据也会被卸载,从而结束该类的生命周期。一个类...

    解析Java类和对象的初始化过程

    类的初始化和对象初始化是JVM管理的类型生命周期中非常重要的两个环节,Google了一遍网络,有关类装载机制的文章倒是不少,然而类初始化和对象初始化的文章并不多,特别是从字节码和JVM层次来分析的文章更是鲜有所见...

    《JVM从入门到入魔》笔记.pdf

    1:JVM内存模型:类加载机制【转载、验证、准备、解析、初始化】+类装载器【装载器分类、加载原则】+运行时数据区【方法区、堆、虚拟机栈、本地方法栈、程序计数器】。 2:垃圾回收:垃圾确定【引用计数法、可达性分析...

    详解Windows下调整Tomcat启动参数的实现方法

    -Xms&lt;size&gt; JVM初始化堆的大小 -Xmx&lt;size&gt; JVM堆的最大值  比如,我想设置初始内存大小为128M,最多占用1G,就是下面的设置: -Xms128m -Xmx1024m  在Linux/Unix下,可以通过在 {tomcat_dir}/bin/catalina.sh ...

    深入JVM内核—原理、诊断与优化

    1、初始化JVM 2、JVM运行机制 3、常用JVM配置参数 4、算法和种类 5、GC参数 6、类 7、性能监控 8、jvm堆分析 9、锁 10、class文件结构 11、字节码执行 12、总结

    JVM工作原理及内存管理机制

    在执行方法时JVM提供了invokestatic、invokevirtual、invokeinterface和invokespecial四种指令来执行 ...(4)invokespecial:JVM对于初始化对象(Java构造器的方法为:)以及调用对象实例中的私有方法时。

    JVM调优相关内容教程吐血整理干货.md

    JVM调优相关 JVM常见参数 堆栈相关 GC相关 其他 Java常用调优命令和工具 JVM调优相关 JVM常见参数 ...设置堆内存初始化大小。...设置永久代的初始化大小为9m,此参数只在jdk8以前的版本有效。 -XX:MaxMetaspaceS

    关于JVM的总结

    类被加载到虚拟机内存开始,到卸载出内存为止,生命周期包含: 加载,验证,准备,解析,初始化,使用,卸载 7个阶段,加载,验证,准备,初始化和卸载这5个顺序是确定的,解析阶段则不一定,他在某些情况下可以在...

    java8看不到源码-Java-Rule-Book:Java的基本概念来回答有关Java工作原理的任何问题

    初始化内存后被调用。 任何成员的声明完全独立于任何其他类/接口。 可以有静态成员和静态块,它们在类中从上到下首先执行。 所有类都有默认构造函数,内部没有语句,默认情况下,直到您手动创建任何构造函数。 它...

    JVM 面试题总结.md

    - 初始化 - 使用 - 卸载 - 在 JVM 中,对象是如何创建的? - 内存分配方式有哪些呢? - 请你说一下对象的内存布局? - 对象头 Header - 实例数据 Instance Data - 对齐 Padding - 对象访问定位的方式有...

    bloom-filter-scala, 用于 Scala的Bloom过滤器,最快的JVM.zip

    bloom-filter-scala, 用于 Scala的Bloom过滤器,最快的JVM Scala的 Bloom filter 概述Bloom过滤器是一种空间高效的数据结构,用于测试某个元素是否是集合的成员。 false 正匹配是可能的,但 false 负数不是。 ...

    JVM 心得分享(加载 链接 初始化)

    下面小编就为大家带来一篇JVM 心得分享(加载 链接 初始化)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧

    java数组初始化笔试题-yvm:[yvm]低性能垃圾回收jvm

    java数组初始化笔试题 | | | | | 这是一个用 C++ 编写的自制 Java 虚拟机,它支持大多数 Java 语言功能,并包含一个基于标记清除的并发垃圾收集器。 此 VM 的主要组件符合 . 它是可运行的,各种语言功能将逐步添加到...

    类加载与类初始化

    JVM把class文件加载到内存,并对数据进行校验、解析和初始化,最终形成 JVM可以直接使用的Java类型的过程。 \quad·加载 \quad\quad将class文件字节码内容加载到内存中,并将这些静态数据转换成方法区中的运行时...

    深入理解JVM内存结构及运行原理全套视频加资料.txt

     第92讲 类加载的过程-初始化 00:19:41  第93讲 类加载器 00:22:41  第94讲 双亲委派模型 00:17:03  第95讲 运行时栈帧结构 00:08:46  第96讲 局部变量表 00:20:48  第97讲 操作数栈 00:08:36  第98讲...

    《剑指offer》JVM面试题总结.pdf

    初始化 使用 卸载 在 JVM 中,对象是如何创建的? 内存分配方式有哪些呢? 请你说一下对象的内存布局? 对象头 Header 实例数据 Instance Data 对齐 Padding 对象访问定位的方式有哪些? 如何判断对象已经死亡? ...

    编程文档JVM、Java基础、.rar

    对象初始化 编译 JiT:即时编译 两大无关性 平台无关性: 每一台平台解释器不同,但是虚拟机相同,跨平台的原因。 一个程序对应一个虚拟机,多个程序对应多个虚拟机, 虚拟机之间数据不共享 什么是平台:操作系统...

    Java + 数组 + 初始化

    Java是基于JVM虚拟机的跨平台语言,一次编写,到处运行; Java程序易于编写,而且有内置垃圾收集,不必考虑内存管理; Java虚拟机拥有工业级的稳定性和高度优化的性能,且经过了长时期的考验; Java拥有最广泛的开源...

    java相关的2024面试题集锦

    - 当初始化一个类的时候,如果发现其父类还没有进行过初始化,则需要先触发其父类的初始化 - 当虚拟机启动时,用户需要指定一个需要执行的主类(包含main方法的那个类)虚拟机会先初始化这个类

    resin-jvm 调优

    设置完成后,实际上就不再使用救助空间了,因此应把SurvivorRatio设成最大值以最大化Eden空间,设置如下: java … -XX:MaxTenuringThreshold=0 –XX:SurvivorRatio=50000 … 4.BEA JRockit JVM的使用 Bea ...

Global site tag (gtag.js) - Google Analytics