java 堆、栈、方法区

堆区:

1.存储的全部是对象,每个对象都包含一个与之对应的class的信息。(class的目的是得到操作指令)

2.jvm只有一个堆区(heap)被所有线程共享,堆中不存放基本类型和对象引用,只存放对象本身 3、new出来的对象,有初始值。

栈区:

1.每个线程包含一个栈区,栈中只保存基础数据类型的对象和自定义对象的引用(不是对象),对象都存放在堆区中

2.每个栈中的数据(原始类型和对象引用)都是私有的,其他栈不能访问。

3.栈分为3个部分:基本类型变量区、执行环境上下文、操作指令区(存放操作指令)。 4、没有初始值

方法区:

1.又叫静态区,跟堆一样,被所有的线程共享。方法区包含所有的class和static变量或方法。

2.方法区中包含的都是在整个程序中永远唯一的元素,如class,static变量。

第一段代码:

public class Test extends Base{

    static{
System.out.println("test static");
} public Test(){
System.out.println("test constructor");
} public static void main(String[] args) {
new Test();
}
} class Base{ static{
System.out.println("base static");
} public Base(){
System.out.println("base constructor");
}
}

输出结果:

base static
test static
base constructor
test constructor

先来想一下这段代码具体的执行过程,在执行开始,先要寻找到main方法,因为main方法是程序的入口,但是在执行main方法之前,必须先加载Test类,而在加载Test类的时候发现Test类继承自Base类,因此会转去先加载Base类,在加载Base类的时候,发现有static块,便执行了static块。在Base类加载完成之后,便继续加载Test类,然后发现Test类中也有static块,便执行static块。在加载完所需的类之后,便开始执行main方法。在main方法中执行new Test()的时候会先调用父类的构造器,然后再调用自身的构造器。因此,便出现了上面的输出结果。

第二段代码:

public class Test {
Person person = new Person("Test");
static{
System.out.println("test static");
} public Test() {
System.out.println("test constructor");
} public static void main(String[] args) {
new MyClass();
}
} class Person{
static{
System.out.println("person static");
}
public Person(String str) {
System.out.println("person "+str);
}
} class MyClass extends Test {
Person person = new Person("MyClass");
static{
System.out.println("myclass static");
} public MyClass() {
System.out.println("myclass constructor");
}
}

输出结果:

test static
myclass static
person static
person Test
test constructor
person MyClass
myclass constructor

类似地,我们还是来想一下这段代码的具体执行过程。首先加载Test类,因此会执行Test类中的static块。接着执行new MyClass(),而MyClass类还没有被加载,因此需要加载MyClass类。在加载MyClass类的时候,发现MyClass类继承自Test类,但是由于Test类已经被加载了,所以只需要加载MyClass类,那么就会执行MyClass类的中的static块。在加载完之后,就通过构造器来生成对象。而在生成对象的时候,必须先初始化父类的成员变量,因此会执行Test中的Person person = new Person(),而Person类还没有被加载过,因此会先加载Person类并执行Person类中的static块,接着执行父类的构造器,完成了父类的初始化,然后就来初始化自身了,因此会接着执行MyClass中的Person person = new Person(),最后执行MyClass的构造器。

第三段代码:

public class Test {

    static{
System.out.println("test static 1");
}
public static void main(String[] args) { } static{
System.out.println("test static 2");
}
}

输出结果:

test static 1
test static 2

虽然在main方法中没有任何语句,但是还是会输出,原因上面已经讲述过了。另外,static块可以出现类中的任何地方(只要不是方法内部,记住,任何方法内部都不行),并且执行是按照static块的顺序执行的。

堆、栈、方法区、静态代码块---Java的更多相关文章

  1. this、static、main方法、静态代码块、final关键字、Runtime类、Cloneable类、类成员的访问控制权限、异常体系

    this表示当前对象,用在方法内部,当某对象调用该方法时,该方法中的this就代表调用该方法的对象: static关键字: 修饰类属性后,该属性就成为该类所有实例的公共属性,修改该属性值,所有的实例的 ...

  2. Java 底层机制(JVM/堆/栈/方法区/GC/类加载)

    转载:https://www.jianshu.com/p/ae97b692614e?from=timeline JVM体系结构 JVM是一种解释执行class文件的规范技术.   JVM体系结构 我翻 ...

  3. java 堆 栈 方法区的简单分析

    Java里的堆(heap)栈(stack)和方法区(method) 基础数据类型直接在栈空间分配, 方法的形式参数,直接在栈空间分配,当方法调用完成后从栈空间回收.   引用数据类型,需要用new来创 ...

  4. JVM堆 栈 方法区详解

    一.栈 每当启用一个线程时,JVM就为他分配一个JAVA栈,栈是以帧为单位保存当前线程的运行状态 栈是由栈帧组成,每当线程调用一个java方法时,JVM就会在该线程对应的栈中压入一个帧 只有在调用一个 ...

  5. java基础课程笔记 static 主函数 静态工具类 classpath java文档注释 静态代码块 对象初始化过程 设计模式 继承 子父类中的函数 继承中的构造函数 对象转型 多态 封装 抽象类 final 接口 包 jar包

    Static那些事儿 Static关键字 被static修饰的变量成为静态变量(类变量) 作用:是一个修饰符,用于修饰成员(成员变量,成员方法) 1.被static修饰后的成员变量只有一份 2.当成员 ...

  6. [二]Java虚拟机 jvm内存结构 运行时数据内存 class文件与jvm内存结构的映射 jvm数据类型 虚拟机栈 方法区 堆 含义

    前言简介 class文件是源代码经过编译后的一种平台中立的格式 里面包含了虚拟机运行所需要的所有信息,相当于 JVM的机器语言 JVM全称是Java Virtual Machine  ,既然是虚拟机, ...

  7. [转载]JAVA内存分析——栈、堆、方法区 程序执行变化过程

    面向对象的内存分析 参考:http://www.sxt.cn/Java_jQuery_in_action/object-oriented.html :尚学堂JAVA300集-064内存分析详解_栈_堆 ...

  8. 从几个sample来学习JAVA堆、方法区、JAVA栈和本地方法栈

    最近在看<深入理解Java虚拟机>,书中给了几个例子,比较好的说明了几种OOM(OutOfMemory)产生的过程,大部分的程序员在写程序时不会太关注Java运行时数据区域的结构: 感觉有 ...

  9. “全栈2019”Java第四十二章:静态代码块与初始化顺序

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...

随机推荐

  1. flutter Could not find the built application bundle

    报错信息Could not find the built application bundle at build/ios/iphoneos/Runner.app. Error launching ap ...

  2. 【运维】使用Serv-U搭建FTP服务器

    1.先安装好Serv-U,并作为系统服务安装 2.打开Serv-U,新建一个域 3.添加用户 4.解决阿里云专有网络的一个问题 遇到一个情景:需要使用Serv-U进行FTP更新软件,其中使用PASV的 ...

  3. python re.findall(rule,data),根据左右边界取值url中参数的值

    import re ''' 取值postid,左边界"postid=",右边界"&" ''' url="http://wwww.baidu.c ...

  4. leetcode上的一些动态规划

    70-爬楼梯 思路:该问题可以理解为经典的“斐波那契数列”问题,但这里需要用动规实现,递归会超时 class Solution { public: int climbStairs(int n) { v ...

  5. leetcode上的位运算

    136-只出现过一次的数字 思路:可以考虑到数字以二进制形式存储,当两个不同的数字异或的时候会是true,所以把数组里的数字都一一处理一遍就可以了. class Solution { public: ...

  6. ROS的使用

    1.输入roscore时出现错误:Unable to contact my own server at 修改: 在.bashrc文件中添加以下内容: export ROS_HOSTNAME=local ...

  7. datetime timestamp使用

    #coding=utf-8 import time import datetime def yes_time(): #获取当前时间 now_time = datetime.datetime.now() ...

  8. 使用jmeter做接口测试----柠檬不萌!

    一.乱码解决方案 1.jmeter查看结果树乱码 (1)在jmeter的bin目录下找到jmeter.properties这个文件,添加上 sampleresult.default.encoding= ...

  9. camunda任务的一些简单操作

    public class ZccTaskService { TaskService taskService; @Before public void init(){ ProcessEngineConf ...

  10. maven命名

    <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpcl ...