前面的几篇都没有太明确地指出 方法区 是什么?现在通过一些资料的收集和学习,下面做一些总结

什么是方法区:

方法区是系统分配的一个内存逻辑区域,是JVM在装载类文件时,用于存储类型信息的(类的描述信息)。

方法区存放的信息包括:

类的基本信息:

1.每个类的全限定名

2.每个类的直接超类的全限定名(可约束类型转换)

3.该类是类还是接口

4.该类型的访问修饰符

5.直接超接口的全限定名的有序列表

已装载类的详细信息

1.      运行时常量池:在方法区中,每个类型都对应一个常量池,存放该类型所用到的所有常量,常量池中存储了诸如文字字符串、final变量值、类名和方法名常量。

2.      字段信息:字段信息存放类中声明的每一个字段的信息,包括字段的名、类型、修饰符。

3.      方法信息:类中声明的每一个方法的信息,包括方法名、返回值类型、参数类型、修饰符、异常、方法的字节码。

(在编译的时候,就已经将方法的局部变量、操作数栈大小等确定并存放在字节码中,在装载的时候,随着类一起装入方法区。)

4.      静态变量:类变量,类的所有实例都共享,我们只需知道,在方法区有个静态区,静态区专门存放静态变量和静态块。

5.      到类classloader的引用:到该类的类装载器的引用。

6.      到类class 的引用:虚拟机为每一个被装载的类型创建一个class实例,用来代表这个被装载的类。

下面分析static的内存分配

  1.  
    public class Dome_Static {
  2.  
     
  3.  
    public static void main(String[] args) {
  4.  
    Person p1 = new Person();
  5.  
    p1.name = "xiaoming";
  6.  
    p1.country = "chinese";
  7.  
    Person p2 = new Person();
  8.  
    p2.name = "xiaohong";
  9.  
    p1.speak();
  10.  
    p2.speak();
  11.  
    }
  12.  
     
  13.  
    }
  14.  
    class Person {
  15.  
    String name;
  16.  
    static String country;
  17.  
    public void speak() {
  18.  
    System.out.println("name:"+name+",country:"+country);
  19.  
    }
  20.  
    }
  1.  
    Output:
  2.  
    name:xiaoming,country:chinese
  3.  
    name:xiaohong,country:chinese
 
`

1.首先,先加载Dome_Static,然后其main函数入栈,之后Person被加载。static声明的变量会随着类的加载而加载,所以在内存中只会存在一份,实例化多个对象,都共享同一个static变量,会默认初始化

2.在栈内存为 p1 变量申请一个空间,在堆内存为Person对象申请空间,初始化完毕后将其地址值返回给p1,通过p1.name和p1.country修改其值

3.在栈内存为 p2 变量申请一个空间,在堆内存为Person对象申请空间,初始化完毕后将其地址值返回给p2,仅仅通过p2.name修改其值

4.打印show方法,进栈,这里就不画图了,对于栈相关的概念不清楚的可以看看在之前发的博客。简单口述下:p1.show()  show方法入栈,在方法的内部有个指向堆内存的this引用,通过该引用可找到堆内存实体,打印country时,可通过该堆内存对象找到对应的类,读取对应静态区中的字段值

最后给大家一道面试题练练手,要求写出其结果(笔试)

  1.  
    public class StaticTest {
  2.  
        
  3.  
        public static int k = 0;
  4.  
        public static StaticTest t1 = new StaticTest("t1");
  5.  
        public static StaticTest t2 = new StaticTest("t2");
  6.  
        public static int i = print("i");
  7.  
        public static int n = 99;
  8.  
        public int j = print("j");
  9.  
         
  10.  
        {
  11.  
            print("构造块");
  12.  
        }
  13.  
         
  14.  
        static{
  15.  
            print("静态块");
  16.  
        }
  17.  
         
  18.  
        public StaticTest(String str) {
  19.  
            System.out.println((++k) + ":" + str + " i=" + i + " n=" + n);
  20.  
            ++n;
  21.  
            ++i;
  22.  
        }
  23.  
         
  24.  
        public static int print(String str) {
  25.  
            System.out.println((++k) + ":" + str + " i=" + i + " n=" + n);
  26.  
            ++i;
  27.  
            return ++n;
  28.  
        }
  29.  
        public static void main(String[] args) {
  30.  
            StaticTest t = new StaticTest("init");
  31.  
        }
  32.  
     
  33.  
    }

结果:

  1.  
    1:j i=0 n=0
  2.  
    2:构造块 i=1 n=1
  3.  
    3:t1 i=2 n=2
  4.  
    4:j i=3 n=3
  5.  
    5:构造块 i=4 n=4
  6.  
    6:t2 i=5 n=5
  7.  
    7:i i=6 n=6
  8.  
    8:静态块 i=7 n=99
  9.  
    9:j i=8 n=100
  10.  
    10:构造块 i=9 n=101
  11.  
    11:init i=10 n=102

这个留给大家去思考,如果一眼便能便知道为什么是这样的输出结果,那么静态方面知识应该比较扎实了

提示一下 :

1.加载的顺序:先父类的static成员变量 -> 子类的static成员变量 -> 父类的成员变量 -> 父类构造 -> 子类成员变量 -> 子类构造

2.static只会加载一次,所以通俗点讲第一次new的时候,所有的static都先会被全部载入(以后再有new都会忽略),进行默认初始化。在从上往下进行显示初始化。这里静态代码块和静态成员变量没有先后之分,谁在上,谁就先初始化

3.构造代码块是什么?把所有构造方法中相同的内容抽取出来,定义到构造代码块中,将来在调用构造方法的时候,会去自动调用构造代码块。构造代码快优先于构造方法。

转载自:https://blog.csdn.net/Wang_1997/article/details/52267688

Jvm方法区以及static的内存分配图的更多相关文章

  1. Java基础-方法区以及static的内存分配图

    转载自: https://blog.csdn.net/Wang_1997/article/details/52267688 前面的几篇都没有太明确地指出 方法区 是什么?现在通过一些资料的收集和学习, ...

  2. java虚拟机 jvm 方法区实战

    和java堆一样,方法区是一块所有线程共享的内存区域,用于保存系统的类信息,类的信息有哪些呢.字段.方法.常量池.方法区也有一块内存区域所以方法区的内存大小,决定了系统可以包含多少个类,如果系统类太多 ...

  3. JVM 方法区内存扩大 以及开启GC

    因为应用使用了OSGi框架,<深入理解JAVA虚拟机>中对使用OSGi时可能产生的方法区溢出有所描述 第一部分: 第二部分 可见,OSGi会动态生成大量Class,在OSGi中,即使是同一 ...

  4. jvm 方法区

    方法区在一个jvm实例的内部,类型信息被存储在一个称为方法区的内存逻辑区中.类型信息是由类加载器在类加载时从类文件中提取出来的.类(静态)变量也存储在方法区中. jvm实现的设计者决定了类型信息的内部 ...

  5. [转]JVM 内存初学 (堆(heap)、栈(stack)和方法区(method) )

    这两天看了一下深入浅出JVM这本书,推荐给高级的java程序员去看,对你了解JAVA的底层和运行机制有比较大的帮助.废话不想讲了.入主题: 先了解具体的概念:JAVA的JVM的内存可分为3个区:堆(h ...

  6. JVM 内存初学 堆(heap)、栈(stack)和方法区(method)

    这两天看了一下深入浅出JVM这本书,推荐给高级的java程序员去看,对你了解JAVA的底层和运行机制有比较大的帮助.废话不想讲了.入主题:先了解具体的概念:JAVA的JVM的内存可分为3个区:堆(he ...

  7. 转:JVM 内存初学 (堆(heap)、栈(stack)和方法区(method) )

    原文地址:JVM 内存初学 (堆(heap).栈(stack)和方法区(method) ) 博主推荐 深入浅出JVM 这本书 先了解具体的概念:JAVA的JVM的内存可分为3个区:堆(heap).栈( ...

  8. JVM内存初学 堆、栈、方法区

    转自: http://www.open-open.com/lib/view/open1432200119489.html 这两天看了一下深入浅出JVM这本书,推荐给高级的java程序员去看,对你了解J ...

  9. JVM 内存初学 (堆(heap)、栈(stack)和方法区(method) )(转载)

    想想面试的时候很多会问jvm这方面的问题虽然还是菜鸟不太能用到现在但是还是了解一下, 找资料的时候看见个大佬写的很好转载到这方便以后自己复习和给大佬做宣传 以下为大佬的博客原文: 这两天看了一下深入浅 ...

随机推荐

  1. MySQL运维及开发规范

    一.基础规范 (1) 使用INNODB存储引擎 (2) 表字符集使用UTF8 (3) 所有表都需要添加注释 (4) 单表数据量建议控制在5000W以内 (5) 不在数据库中存储图.文件等大数据 (6) ...

  2. bzoj3140: [Hnoi2013]消毒(二分图)

    题目描述 最近在生物实验室工作的小T遇到了大麻烦. 由于实验室最近升级的缘故,他的分格实验皿是一个长方体,其尺寸为a*b*c,a.b.c 均为正整数.为了实验的方便,它被划分为a*b*c个单位立方体区 ...

  3. Python和FTP

    1.HTTP主要用于基于Web的文件下载以及访问Web服务,一般客户端无须登录就可以访问服务器上的文件和服务.大部分HTTP文件传输请求都用于获取网页(即将网页文件下载到本地). 2.FTP主要用于匿 ...

  4. sap alv 单元格行列邓颜色设定(记录一下网址,供下次使用)

    https://www.cnblogs.com/mingdashu/p/color_alv.html

  5. 华为敏捷/DevOps实践:如何开好站立会议

    大家好,我是华为云的产品经理 恒少: 作为布道师和产品经理,出差各地接触客户是常态,经常和华为云的客户交流.布道.技术沙龙,但是线下交流,覆盖的用户总还是少数. 我希望可以借线上的平台,和用户持续交流 ...

  6. JS的类型转换

    首先我们要知道,在 JS 中类型转换只有三种情况,分别是: 转换为布尔值 转换为数字 转换为字符串 我们先来看一个类型转换表格 转Boolean 在条件判断时,除了 undefined, null,  ...

  7. Web安全工程师(进阶)课程表

    01-SQL注入漏洞原理与利用 预备知识: 了解HTTP协议,了解常见的数据库.脚本语言.中间件.具备基本的编程语言基础. 授课大纲: 第一章:SQL注入基础 1.1 Web应用架构分析1.2 SQL ...

  8. composer.json 配置设置

    配置文件的值为 key:val 必须双引号包裹 一.配置文件 名字 name包名称由用户名名称和仓库名称组成包版本限制来请求Monolog软件包 1.0.*.这意味着1.0开发分支中的任何版本,或大于 ...

  9. [Leetcode]014. Longest Common Prefix

    public class Solution { public String longestCommonPrefix(String[] strs) { if(strs == null || strs.l ...

  10. 12-----BBS论坛

    BBS论坛(十二) 12.1.图形验证码生成 (1)utils/captcha/init.py import random import string # Image:一个画布 # ImageDraw ...