`
jgnan
  • 浏览: 87501 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

每天简单JAVA教学:JVM的内存管理,static的用法

阅读更多
今天的主题是介绍static和final这两个指示器的用法。但是为了说明它们两个的具体作用之前,我觉得还是有必要先说说jvm的内存管理。

关于这部分,网上已经有很多不错的文章了,比如这个:
http://topic.csdn.net/u/20090602/10/bd9d4ba2-dbeb-49b3-8651-67c5de2b228a.html

官方的白皮书:
[url]https://java.sun.com/j2se/reference/whitepapers/memorymanagement_whitepaper.pdf
[/url]

而关于今天的主题,大家只需要关心官方版本的一句话就好,垃圾回收等内容大家可以有兴趣的就读一下:

在JVM里面,内存被划分为3个区间:Young,Old和Permanent。就是新生代,老生代及永生代。大部分的初始化都是在新生代内存进行的,然后存活时间较长的或者一部分大对象被保存到老生代。而那些便于JVM管理的不会去主动回收的对象,都保留在永生代。

而关于最后一个区间,官方的答案是一般关于类和方法的描述对象,以及类和对象本身,都会被保存到永生代里面!

所以。我们写的.java文件里面的每个class到了jvm里面就会变成一个单独的对象。这个我个人习惯叫类模版,因为它的确很像模版。然后我们要用的往往不是这个模版本身,而是基于这个模版产生的一份拷贝,也就是它的一个实例(instance)。所以,在上一个例子里面,我们需要使用new这个关键字,来在JVM的新生代生成一个Modifier对象的实例。()表示调用默认的Modifier的构造函数。构造函数往往会在创建实例的时候进行一些初始化动作,以使得每个创建的实例会代一些我们预期的初始参数。而且一个模版可以带有多个构造函数,构造函数也可以接受各种参数,例如:

package constructor;

public class ConstructorDemo {
    /**
     * 重载了默认不带参数的构造函数,初始化实例时会执行里面的命令
      */
    public ConstructorDemo()
    {
        System.out.println("I'm the default constructor!");
    }
	
    /**
     * 如果调用new ConstructorDemo(name)来构造实例,则控制台显示不同的内容
      * @param name
     */
    public ConstructorDemo(String name)
    {
        System.out.println("New instance with name : "+name);
    }
}


大家可以自己去用这两个构造函数来初始化实例试试有什么不同。

那么,大家就可以理解,其实class的内容,以及里面的方法,在JVM里面都有一段内存保存着其内容,但是其实并没有直接分配一段可执行的内存空间给它们。所以我们不能够直接调用没有加static的方法。而且由于自动内存管理机制,我们也很难保证同一个类模版的新实例固定在某个地址段里面。

但是static字段允许我们直接让类模版里面的某些方法或字段在直接在类模板的内存段里面划分出来。让这些static方法或者字段可以直接被外部直接访问永生代的一个固定地址来访问。因此,访问static的方法时,可以不创建某个类的实例而是直接通过类模版对象来访问:

package staticnfinal;

public class StaticDemo {
    public static void main(String[] args) {
        //调用static方法:
        StaticDemo.staticMethod();
        //调用非static方法
         StaticDemo demo = new StaticDemo();
        demo.notStaticMethod();
        /*
         * 通过实例来访问静态方法也是可以的,但是我们不推荐这种做法,
         * Eclipse也会有warning
         */
        demo.staticMethod();
    }
	
    public static void staticMethod()
    {
        System.out.println("I can be call without creating new instance");
    }
	
    public void notStaticMethod()
    {
        System.out.println("I must be call after creating new instance!");
    }
}


最后一个例子大家会发现通过实例也可以调用staticMethod,但是我们不推荐这种做法。

大家可能会问,加static和不加static有什么区别?什么时候应该加,什么时候不应该加?其实问题是这样的。static的方法或字段会占用永生代的内存,前面已经说过这段内存是不会主动去清空它的,所以jvm也是默认往里面放最常用的东西,如类模版对象,方法模版对象以及对它们的映射对象等。所以,如果我们要把方法或者字段定义为static,就一定要是那种会被经常访问到的东西,比如系统的全局变量啊,一些常用的工具方法等等。而不能乱用,因为用多了,应用的内存就会高居不下,因为动态内存少了,固定内存太多。

虽然每次要用方法要开个新的实例貌似更加麻烦及占内存,但是如果从长远来看,由于实例一旦没有被进一步调用就会被自动清理,所以这种方式会很省空间。而且在多线程的情况下,这种每个实例自己一个方法调用空间的做法,也会避免了一些同步问题。所以如果不是是非必要的话,大家还是少用static来生命对象为妙。

明天会介绍方法继承,重构及重载,还有final标识符。
分享到:
评论
发表评论

文章已被作者锁定,不允许评论。

相关推荐

    最新java面试专题01-JVM

    JVM内存结构:JVM的内存结构主要包括堆内存、方法区、栈(包括Java虚拟机栈和本地方法栈)、程序计数器等。堆内存是所有线程共享的内存区域,用于存放对象实例;方法区保存已加载的类信息、常量、静态变量和编译后的...

    Java常见面试问题整理.docx

    直接内存:不受JVM GC管理,直接内存并不是虚拟机运行时数据区的一部分,也不是Java 虚拟机规范中定义的内存区域。在JDK1.4 中新加入了NIO(New Input/Output)类,引入了一种基于通道(Channel)与缓冲区(Buffer)的I/...

    openwhisk-runtime-java:Apache OpenWhisk运行时Java支持以Java和其他JVM托管语言编写的Apache OpenWhisk函数。

    适用于Java的Apache OpenWhisk运行时变更日志快速Java动作Java动作是具有称为main的方法的Java程序,该方法具有如下确切的签名: public static com.google.gson . JsonObject main( com.google.gson . JsonObject )...

    Java 基础学习笔记:数据类型,常见运算,final & static,Java 常见类,异常 & 反射

    Java 基础学习笔记,主要包括: 10_Java常见对象.md 10_Java常见对象_2.md 1_数据类型.md 3_运算.md ...由于Java的高性能和稳定性,许多大型企业和互联网公司选择使用Java开发核心业务系统和高并发的We

    Java文件转换为 Exe 可执行文件

    配置方法为:指明 jvm.dll 所在相对位置或者绝对位置。 举例: 对于前面的例子 test.exe,对应的配置文件为 test.cfg。 如果将 jre 的文件夹 "jre1.5.0" 随同 test.exe 一同发布,则配置文件 test.cfg 可以写成: ...

    java8rt.jar源码-mini-jvm:Go语言实现的JVM,实现了部分字节码的解释执行,学习JVM使用

    使用Go实现的Java虚拟机(不完整),解释执行,仅学习JVM使用; Mini-JVM首先会从classpath中加载主类的class文件,然后找到main方法的字节码解释执行;执行过程中如果遇到新的类符号引用,则会通过全限定性名再从...

    jvm-tail-recursion:Java字节码中的尾部递归调用的优化器库

    jvm-tail-递归在Java字节码上执行尾部递归优化的Java库。它只是将函数中的最终递归方法调用替换为goto到同一函数的开头。该项目使用执行字节码操作。例子倒数至零一个简单的尾递归函数,倒数为零:前后static void ...

    Java关键字final、static使用总结

    final方法不能被子类的方法覆盖,但可以被...用static修饰的代码块表示静态代码块,当Java虚拟机(JVM)加载类时,就会执行该代码块,下面通过本文给大家分享Java关键字final、static使用总结,感兴趣的朋友一起看看吧

    java 面试题 总结

    忘记或者错误的内存回收会导致程序或系统的不稳定甚至崩溃,Java提供的GC功能可以自动监测对象是否超过作用域从而达到自动回收内存的目的,Java语言没有提供释放已分配内存的显示操作方法。 25、short s1 = 1; s1 =...

    Java JDK 7学习笔记(国内第一本Java 7,前期版本累计销量5万册)

     《java jdk 7学习笔记》是作者多年来教学实践经验的总结,汇集了教学过程中学生在学习java时遇到的概念、操作、应用或认证考试等问题及解决方案。  《java jdk 7学习笔记》针对java se 7新功能全面改版,无论是...

    JAVA面试题集合面试技能大全

    Java语言中一个显著的特点就是引入了垃圾回收机制,使c++程序员最头疼的内存管理的问题迎刃而解,它使得Java程序员在编写程序的时候不再需要考虑内存管理。由于有个垃圾回收机制,Java中的对象不再有“作用域”的...

    java面试宝典

    31、java 中会存在内存泄漏吗,请简单描述。 11 32、abstract 的method 是否可同时是static,是否可同时是native,是否可同时是synchronized? 11 33、静态变量和实例变量的区别? 11 34、是否可以从一个static 方法...

    JVM面试专题

     3、解释内存中的栈(stack)、堆(heap)和静态区(static area)的用法 4、Perm Space中保存什么数据?会引起OutOfMemory吗? 5、什么是类的加载 6、如何⾃定义⼀个类加载器?你使⽤过哪些或者你在什么场景下需要⼀个⾃...

    JAVA基础课程讲义

    JVM(JAVA VIRTUAL MACHINE) 16 Java运行时环境JRE(Java Runtime Environment) 17 JAVA语言应用范围 18 第一个JAVA程序 18 JAVA开发环境搭建 18 一个典型的JAVA程序的编写和运行过程 19 第一个程序常见错误 20 第一个...

    JAVA面试题最全集

    68.GUI布局管理器的使用,FlowLayout,BorderLayout,GridBagLayout 69.如何构造一棵树?选择树的一个节点时,如何得到这个节点? 70.向编辑框中输入字符时,如何控制只输入整数? 71.描述使用JDBC连接数据库的...

    菜鸟进阶练习(01)

    1、在java中,在同一包内,类Cat里面有个公有方法sleep(),该方法前有static修饰,则可以直接用Cat.sleep()。 【正确答案】正确; 【解析】可以直接使用本类中的静态方法,静态方法可以直接使用 类名.方法。 2、Java...

    Java入门教程(微学苑)-part1

    最好的最简单的Java入门教程。 目录 1 Java概述 1 1.1 Java语言概述 1 1.2 Java虚拟机以及跨平台原理 2 1.3 关于JVM的执行效率 2 1.4 客户端市场的折戟 3 1.5 Java的主要就业方向 3 1.5.1.1 Web开发 3 1.5.1.2 ...

    张孝祥Java就业培训教程.pdf

    在第二章中,全面地讲解Java的基本语法知识,对基本语法的讲解也不是泛泛而谈,而是在其中贯穿各种实际应用中的巧妙用法和注意事项。在第三章和第四章中,透彻系统地讲解了面向对象的思想和应用。在以后的章节中,用...

    JAVA--达内培训笔记

    JAVA--达内培训笔记】 1、Java之父Golsling 1995年5月23日 Java诞生 1998年12月 1.2版本 Java2 J2SE J2EE J2ME 2004年12月 1.5版本(5.0) Java JavaSE JavaEE JavaME 2、Java SE --- Java标准平台 Java EE -...

Global site tag (gtag.js) - Google Analytics