从单例模式看JVM内幕

原创 2012年03月29日 18:28:17

先看一道简单而变态的面试题:
class Singleton{

private static Singleton singleton = new Singleton();  //
public static int counter1;
public static int counter2 = 0;
//private static Singleton singleton = new Singleton();  //

public Singleton(){
  counter1++;
  counter2++;
}

public static Singleton getInstance(){
  return singleton;
}
}
//测试类
public class Mytest {
public static void main(String[] args) {
  Singleton singleton = Singleton.getInstance();
  System.out.println("counter1:"+singleton.counter1);
  System.out.println("counter2:"+singleton.counter2);
}
}

//输出结果
private static Singleton singleton = new Singleton();语句在位置①,结果:
counter1:1
counter1:0
private static Singleton singleton = new Singleton();语句在位置②,结果:
counter1:1
counter1:1

JVM加载、连接、初始化.class文件原理如下:
/*
* 1.虚拟机的生命周期:结束的几种方式:正常结束、System.exit()、异常、操作系统错误
* 2.加载、连接、初始化
*   加载:class文件二进制加载到内存
*   连接:
*        验证:确保加载类的正确性
*        准备:为类得静态变量分配内存,并将其默认为初始值
*        解析:把类得符号引用转换为直接引用
*   初始化:为类的静态变量赋予正确的初始值
*
* java对类的使用方式2种:主动使用、被动使用
* 主动使用(6种):
*   创建类得实例:new一个实例
*   访问静态变量
*   调用类得静态方法
*   反射:Class.forName("com.xxx.xxx")
*   初始化类的子类
*   java虚拟机启动时被标明为启动类得类:有main方法的入口
*
* ***所有java虚拟机实现必须在每个类或接口被java程序“首次主动使用”时才初始化它们
*
* 1.类的加载
*   加载过程:.class文件中二进制读入内存,将其放在运行时数据区的方法区,然后在堆区创建一个java.lang.Class对象,用来封装类在方法区的数据结构
*   加载方式:本地系统加载
*          网络下载.class文件:URLClassLoader
*         从zip、jar归档文件中加载文件
*        数据库中提取.class文件
*        java源文件动态编译的.class文件
*  加载器:
*    java自带加载器:
*         a.根类加载器:bootstrap (c++编写的,在程序中无法在java代码中获得该类)
*         b.扩展加载器:extension (java写的)
*         c.系统(应用)加载器:system (java写的)
*    用户自定义加载器:java.lang.ClassLoader子类
* 2.连接:将已经读入到内存的类的二进制数据合并到虚拟机运行时环境中去
*   验证:
*    类的文件结构检查:java类文件固定格式
*    语义检查:符合java类语法规范:如final类无子类
*    字节码验证:字节码流 = 操作码单字节指令流,防止人为生成.class文件
*    二进制兼容性验证:一个类的方法调用另外一个类得某一方法,但方法不存在
*   准备:为类得静态变量分配内存,并将其默认为初始值
*   解析:把类得符号引用转换为直接引用
*    例子:在Worker类gotoWork()方法会引用到Car类的run()方法
*    public void gotoWork(){
*     car.run(); //这段代码在Worker类的二进制代码中表示为符号引用
*    }
*    //在Worker类的二进制数据中,包含了一个对Car类的run()方法的符号引用,它由run()方法的全名和相关描述符组成。在解析阶段,java虚拟机会把这个符号引用替换为一个指针(c语言真正的指针),该指针指向Car类的run()方法在方法区内的内存位置,这个指针就是直接引用
* 3.初始化:为类得静态变量赋予初始值
*   静态变量赋初始值有2种途径:1.在静态变量声明处。2.在静态代码块中static{}
*/

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

由单例模式探讨JVM的内存管理机制

在软件设计方面,分工越发的细致,对象的创建和使用已被明显分开,而作为消耗内存最严重的创建对象过程,必须对其进行约束,作为创建型模式的singleton,保证应用程序中某一个实例有且仅有一个,可以很显著...

单例模式

  • 2015-06-24 10:08
  • 21KB
  • 下载

单例模式

  • 2013-11-14 14:44
  • 24KB
  • 下载

【Redis学习】Redis管理命令总结

1、键管理之前通过对五种数据类型的操作命令的学习发现,Redis在对每种数据进行处理之前,都要先指定该数据的key,然后再指定对该数据进行何种操作。Redis中的key有点类似于Java中的变量名。对...
  • lmb55
  • lmb55
  • 2016-03-14 13:16
  • 736

单例模式详解

  • 2014-06-06 00:14
  • 25KB
  • 下载

单例模式学习

《深入分析JavaWeb技术内幕》读书笔记六.JVM

JVM体系结构 何谓JVM JVM体系结构详解 类加载器 执行引擎 Java内存管理 JVM工作机制 机器如何执行代码 ...

耦合和单例模式的理解

  • 2014-08-18 09:28
  • 21KB
  • 下载

java单例模式

内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)