黑马程序员-java内存结构和对象创建的过程

黑马程序员入学Java知识——精华总结 黑马程序员入学Java知识——精华总结   J2SE部分,Java高新技术部分,7K面试题部分等黑马入学要求的知识点总结!   一、黑马程序员—java概述与基础知识 6 1、何为编程? 6 2、Java语言概述,历史、特点 6 3、什么是跨平台性?原理是什么?JVM 7 4、Jre和Jdk的区别? 7 5、java虚拟机JVM 8 6、 Java程序运行机制 8 7 阅读详情

---------------------- ASP.Net+Unity开发、.Net培训、期待与您交流! ----------------------

      

      在学到毕老师视频中介绍关于java内存结构的时候,感觉这些内容特别重要。结合视频和对《深入理解java虚拟机》这本书的一些理解写了这篇日记。

java内存分配和管理是java的核心技术之一。一般java程序运行时会涉及到如下几个存储区域:

程序计数器:
可以看做是当前所执行字节码的行号指示器。通常是改变计数器字节码的值来抉择下一步索要执行的代码,程序员不直接控制。

寄存器:
在程序中我们无法直接控制,由编译器管理。

栈区:  
1,每个线程包含一个栈区,栈中只保存基础数据类型的对象和自定义的对象的引用以及局部变量。

2,每个栈中的数据都是私有的,其他栈不能访问。

3,当局部数据用完时,所占内存空间会自动释放。

JVM栈一个最大的用处是为执行java方法服务的,每一个方法被执行的时候都会同时创建一个栈帧用于存储局部变量表,操作栈,动态链接,方法出口等信息。

每一个方法从调用直至执行完成的过程都对应着一个栈帧在虚拟机中从入栈到出栈的过程。
栈的优势在于存取速度比较快,仅次于寄存器。缺点是存储在栈中的数据的大小和生存周期是确定的,缺乏灵活性。

堆区:
1,通过new建立的数组和对象都存储在堆中。

2,每一个对象都有相应的内存地址值。

3,对象中的变量都有默认初始化值。

4,数组和对象在没有引用变量指向它的时候,才变成垃圾,不能再被使用,但是仍然占着内存,在随后的一个不确定的时间被垃圾回收器释放掉。

另外要明确的是每一个Java应用都唯一对应一个JVM实例,每一个实例唯一对应一个堆。在java堆中还必须包含能查找到对象类型数据(如对象类型,父类,实现的接口,方法等)的地址信息,
这些类型数据(优先于对象存在)都存储在方法区中。
堆的优势在于可以动态地分配内存的大小,生存周期也不必事先告诉编译器,因为它是运行时动态地分配内存的,并用垃圾回收机制回收那些不用的数据。缺点是存取速度比较慢。

方法区:
方法区本身又分为以下几个区域:
1.静态数据区,存放静态数据的地方

2.常量区:就是下面要介绍的常量池。

3.代码区:存放方法代码的区域
总之,方法区是JVM在装载类文件时,用于存储类型信息的(类的描述信息)地方,是一片给各个线程共享的内存区域。

常量池:
常量池是Class文件结构中与其他项目关联最多的数据类型,它本身是方法区中的一个数据结构。在方法区中,每个类型都对应一个常量池,
常量池中存储了诸如文字字符串、final变量值、类名和方法名常量。JVM把常量池组织为入口列表的形式,可通过索引来访问常量池中的各个入口,
并用入口标识来表示该常量池存储的数据类型。常量池在编译期间就被确定,并被保存在已编译的.class文件中的一些数据,一般分为两大类,字面量和引用量。
字面量入全面提到的文本字符串,final变量等。类名和方法名属于引用量。
引用量最常见的一种用法是在调用方法的时候,根据方法名找到方法的引用,并以此定位到函数体进进行函数代码的执行。
引用量:
1,类和接口的权限定名。

2,字段的名称和描述符。

3,方法的名称和描述符。

通过String来了解常量池,例如有如下五个赋值语句:
String str1 = new String("abc");
String str2 = new String("abc");
String str3 = "abc";
String str4 = "abc";
String str5 = "ab"+"c";


System.out.println(str1 == str2); //1

System.out.println(str1 == str3); //2
System.out.println(str3 == str4); //3
System.out.println(str4 == str5); //4

程序依次输出的值是:
false
false
true
true

首选要说名的是用String str = "abc";这种方式创建的字符串对象是存储在常量池中的,JVM首先去字符串常量池里找有没有"abc",没有,则将"abc"放入常量池,否则直接将指向常量池中"abc"的引用给str。而通过new创建的字符串对象是存储在堆内存中的。"=="运算符比较的是对象的引用值,str1和str2都有自己的对应的堆空间,故引用值不等,输出false。通过new创建的对象永远都不可能存储在常量池空间!!,故第二个也输出false。java确保常量池中的一个字符串常量只有一个拷贝。故第三个输出为true。当一个字符串有多个字符串常量连接而成时,它本身也是一个字符串常量,所以str5本身也是一个字符串常量的引用,它指向常量池中的"abc",从而第四个也输出true。


以创建Pernson对象为例,分析对象创建过程中在内存中的分配情况以及方法的调用过程。
class Person
{
   private String name;
   private int age;
   private static String Country = "CN";

   DemoTest dTest = new DemoTest();

   public Person(String name, int age)
  {
       System.out.println("这是person的构造函数");
       this.name = name;
       this.age = age;
   }

  {
       System.out.println("这是person的构造代码块");
   }

   static 
  {
       System.out.println("这是person类的静态代码块");
   }
   

   public void setName(String name)

  {
       this.name = name;
   }

   public void show()
  {
      System.out.println("name = "+name + "::"+"age = "+age);
   }

   public static void showCountry()
  {
      System.out.println("Country = "+Country);
   }
}

class DemoTest
{
     public DemoTest()
    {
         System.out.println("这是一个测试的类");
     }
}

public class test
{
     public static void main(String[] args)
    {
         Person p = new Person("zhangsan",11);
         p.setName("lisi");
         p.show();
     }
}

main函数执行后的结果为:

这是person类的静态代码块
这是一个测试的类
这是person的构造代码块
这是person的构造函数
name = lisi::age = 11

过程分析:
首先要明确的一点是: 类的成员变量在不同对象中各不相同,都有自己的存储空间(存储在各自对象所占用的堆内存空间中)。
而类的方法却是该类的所有对象共享的,它们存放在了方法区中,各方法的引用存储在了常量池中。方法区优先于对象存在而且对象只保存了成员变量和一些地址信息。

首先栈中的main函数执行Person = new Person("zhangsan",11);这个简单的语句会涉及到如下几个步骤:
1,由于是要创建Person类对象,java虚拟机(JVM)先去找Person.class文件,如果有的话,将其加载到内存。

2,将类型信息(包括静态变量,方法等)加载进方法区。

3,执行该类中static代码块,如果有的话,对Person.class类进行初始化。(此时输出‘这是person类的静态代码块’)

4,到这时才进行堆内存空间的开辟,并为对象分配首地址。

5,在堆内存中建立对象的成员属性,并对其进行初始化(先进行默认初始化再进行显示初始化。(此时输出  ‘这是一个测试的类’)

6,进行构造代码块的初始化,由此看出构造代码库初始化的优先级要高于对象构造函数的初始化。 (此时输出 ‘这是person的构造代码块’)

7,对象的构造函数进行初始化。(此时输出 ‘这是person的构造函数’);

8,将堆内存中的地址付给栈内存中的p变量。

接下来执行p.setName("lisi")过程如下:
1,首先在栈中为对象p开辟一个栈空间供执行方法时使用,每个对象在执行自己的方法的时候得到自己的一份栈空间。然后根据引用p定位到堆中的对象,再根据对象持有的引用定位到方法区中的函数setName(),同时获得方法的字节码(引用)。

2,在栈中压入一个局部数据作为方法的实参,通过方法字节码,程序计数器跳转到相应的方法中执行,
并将调用此方法的对象的引用赋值给this,接着便将实参赋值给this所指向的对象在堆中相应的成员变量。

3,方法调用结束,会通过执行类似汇编中的ret指令,自动释放局部数据所占用的空间,并重置程序计数器的值以执行main函数中调用方法语句后的下一条语句。

注意: 每一个不同的对象(由相同的类创建而成)在执行同一个函数时,引用的是方法区中同一个字节码!!

执行p.show()的过程与执行p.setName("lisi")的过程类似。(输出 ‘name = lisi::age = 11’)。

以上是我的java虚拟机机制的一些理解,由于JVM的复杂性,完全理解它是很困难的,仅仅是写下这篇浅显的日志也花费了大量的时间去理解。


---------------------- ASP.Net+Unity开发、.Net培训、期待与您交流! ----------------------详细请查看:www.itheima.com

Java面试宝典2018:黑马程序员版 Java是一种面向对象的编程语言,自1995年由Sun Microsystems公司推出以来,因其跨平台性、安全性和简易性而广泛应用于企业级开发。Java代码在运行时通过Java虚拟机(JVM)转换成机器码,这意味着Java程序可以在任何安装了JVM的平台上执行,无需修改。| 方法 | 描述 | 阅读详情

相关推荐

react_blog:技术胖个人使用博客系统

React钩子+ Next.js + Egg.js博客系统 系统介绍 这是一个适合写IT技术文章的博客系统,主要使用的技术是React Hooks + Next.js + Egg.js + MySql + Ant Design。程序员熟悉的技术,因此适合前端程序员使用。 对Markdown的解析使用marked + highlight的方式,这也是目前最成熟的R解决方案。 博客预览地址: : 博客预览图片: 为了更好的使用这个博客,我还出了44集视频,你可以进行观看学习,学习完成你一定可以轻松使用这套系统。 01,博客实战的课程介绍: ://jspang.com/detailed?id 52#toc21 02,项目前端基础开发环境的构建: ://jspang.com/detailed id 52#toc25 03,制作博客公共头像并形成组件: ://jspang.co

React 免费教程 (七)JSPang博客第一节源码。

import React, { Component } from 'react' import '../public/style/components/header.css' import {Row,Col,Menu } from 'antd' import { HomeOutlined,YoutubeOutlined,SmileOutlined } from '@ant-design/icons' const Header=()=>{ return( <d.

琼楼玉宇 507

SAP Ariba Procurement_Catalogs

SAP Ariba Procurement_Catalogs Search Functionality PunchOut Catalogs Spot Buy catalog

CZxx1的博客 1011

对象创建的过程

不可变对象指对象一旦被创建,状态就不能再改变,任何修改都会创建一个新的对象。如StringInteger及其它包装类;不可变对象最大的好处是线程安全。

张紫娃的博客 1421

STM32的DMA模块及Protues仿真实验

(一)DMA简介      DMA(Direct Memory Access,直接存储器访问), 用于在外设与存储器之间以及存储器与存储器之间提供高速数据传输。可以在无需任何 CPU 操作的情况下通过 DMA 快速移动数据。这样节省的 CPU 资源可 供其它操作使用。      STM32F407共有两个 DMA 控制器,总共有 16 个数据流(每个控制器 8 个),每一个 DMA 控制器都用于管理 一个或多

weixin_45930204的博客 2849

【机电杂谈2】BLDC和PMSM的特点和区别

在日常生活中,小到电动玩具,大到电动汽车,永磁电机的身影可以说是无处不在。有刷直流电机、无刷直流电机、永磁同步电机由于其结构和输出特定的不同也被应用到不同的场合。如果你经常拆一些玩具和家电,就会看到大量的有刷直流电机和无刷直流电机,而永磁同步电机主要应用在高精度的工业伺服和电动汽车领域。本文就从电机的结构和控制方面,对这几种常见的永磁电机做简单的梳理和归纳。

2934

【weex】(1):超级赞,【jspang 发布的 Weex 学习资料 17 集,免费视频】

关于jspang http://jspang.com/ 胜洪宇 外号:技术胖,80后屌丝程序猿、已婚、丰富Web前端开发经验 jspang,我还以为是 JavaScript pang呢。支持下他呢。还自己做网站。 这个视频是免费的,不要从taobao,qq 买视频资料 !!! 视频地址: 【技术胖的WEEX入门到实战视频教程】 https://www.bilibili....

freewebsys的专栏 3644

Jetson nano/nx使用麒麟arm版向日葵实现远程控制

Jetson nano/nx使用麒麟arm版向日葵实现远程控制1、安装向日葵软件2、运行Sunlogin Client3、向日葵闪退问题4、重启系统5、重启后黑屏问题 特别提醒: 本博客的第3步切换桌面管理环境到lightdm,存在重启后开机黑屏的风险,我在自己的nano/nx上都没有问题,但帮一个同学的nx配置时,切换到lightdm,重启开机却出现了黑屏,所以执行第3步的话要有心理准备,黑屏解决方法见第5步,特此提醒。

胡乱学点东西 2万+

对象的创建过程

对象创建过程

qq_51302219的博客 1058

Python学习第32天:Web前端入门

本文介绍了Web前端开发三大核心技术:HTML、CSS和JavaScript。首先概述了HTML的发展历程和HTML5新特性,详细讲解了常用HTML标签如文本、列表、链接、图像、表格、表单等。其次介绍了CSS的基础语法、选择器、颜色字体设置、盒子模型和布局定位方法。最后简要提及JavaScript为网页添加交互功能的作用。文章为Python开发者提供了前端技术的基础知识,帮助理解网页的结构、样式和行为实现原理。

tigerhhzz的博客 1910

[Python] -项目实战10- 用 Python 自动化批量重命名文件

本文介绍了使用Python实现文件批量重命名的技术方法。主要内容包括:1)使用os和pathlib模块进行基础文件操作;2)提供多种实用脚本示例,如添加序号、替换字符、添加时间戳等;3)进阶功能包括用户输入和错误处理;4)GUI工具实现方案;5)常见问题与优化建议。文章详细讲解了从简单到复杂的批量重命名实现方法,帮助读者快速掌握这一提高工作效率的技能。建议开发者注意路径处理、错误管理等细节,确保脚本稳健运行。

每日出拳老爷子的博客 815

创建对象的步骤

一 创建对象的步骤图解 二说明 1 判断对象对应的类是否加载、链接、初始化。 虚拟机遇到一条 new 指令,首先去检查这个指令的参数能否在 Metaspace 的常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否已经被加载,解析和初始化。(即判断类元信息是否存在)。如果没有,那么在双亲委派模式下,使用当前类加载器以 ClassLoader + 包名 + 类名 为 key 进行查找对应的 .class文件,如果没有找到文件,则抛出 ClassNotFoundException 异.

实践求真知 4048

WiFi偏门协议(四):增强的传输机制802.11aa

区分Unicast和Multicast的优先级,以及设定不同的重传次数,以细化EDCA机制。 SCS(StreamClassification Service) 如上图,在VI,VO内各自又增加了一个queue, 对应不同的MAC header。VI和VO内的两个queue可以分别对应UC和MC。这样就提供了同一个AC内的更细粒度的优先级区分。当然还可以使用Drop Eligibility Indication子域来区分不同的重传次数。 改善Multicast数据传...

reekyli的专栏 1790

分享~~黑马程序员-java内存结构和对象创建的过程

[code="html"] 测试 [/code] [code="java"] String str1 = new String("abc"); String str2 = new String("abc"); String str3 = "abc"; String str4 = "abc"; String str5 = "ab&

iteye_7569的博客 168

2022年全国职业院校技能大赛高职组大数据技术与应用赛项赛卷⑩—解析答案

工业互联网是工业全要素、全产业链、全价值链的全面连接,是人、机、物、工厂互联互通的新型工业生产制造服务体系,是互联网从消费领域向生产领域、从虚拟经济向实体经济拓展的核心载体,是建设现代化经济体系、实现高质量发展和塑造全球产业竞争力的关键支撑。加快发展工业互联网产业,不仅是各国顺应产业发展大势,抢占产业未来制高点的战略选择,也是我国推动制造业质量变革、效率变革和动力变革,实现高质量发展的客观要求。 为完成工业大数据分析工作,你所在的小组将应用大数据技术,以Scala作为整个项目的基础开发语言,基于大数据平台综

我是网络安全兼技能大赛工程师,专注网络安全技术学习与技能大赛实战!持续分享最新的技术文章,帮你少走弯路,一起在技术赛道上进步~ 579

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

黑马程序员Java笔记

输出打印、参与运算、修改记录的值。

m0_68735537的博客 4474

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

黑马程序员——创建对象与内存分析

------- android培训、java培训、期待与您交流! ----------           创建对象过程中,会分配内存空间。下面通过一个例子说明Java虚拟机是如何分配内存空间的。       下面代码中,有一个Person类,该Person类中有两个成员变量:name和age,主函数为PersonTest: package com.itheima.entranc

LanceDream的专栏 859

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

【黑马程序员JAVA笔记+完整代码】DAY05-08 面向对象编程

黑马Java网课

CherryTaylor的博客 2099

黑马Java——面向对象

类的组成是由属性和行为两部分组成。

pangyaqi的博客 1361

黑马程序员Java教程学习笔记(三)

黑马程序员Java教程学习笔记(三)

末初 · mochu7 2511

在JVM中,Java对象是如何创建、存储和访问的?

在Java虚拟机(JVM)中,Java对象的创建、存储和访问是Java程序运行的核心部分。这个过程涉及到内存管理、对象模型以及运行时数据区域的概念。

Itmastergo的博客 601

黑马程序员JVM笔记01-内存结构

内存结构 程序计数器(Program Counter Register) 由寄存器实现,用来记住下一条JVM指令的执行地址 线程私有 不存在内存溢出 虚拟机栈 线程运行时需要的内存空间,一个线程对应一个栈 每个线程只能有一个活动栈帧,即正在执行的方法(栈顶) 问题: 1、垃圾回收是否涉及栈内存? 2、栈内存是否越大越好? 3、方法内的局部变量是否线程安全? ...

weixin_44983669的博客 2930

探索Java集合的奥秘:黑马程序员的宝藏笔记

探索Java集合的奥秘:黑马程序员的宝藏笔记 【下载地址】黑马程序员Java学习笔记集合 本资源文件包含了黑马程序员的Java学习笔记,重点聚焦在集合部分。内容包括源代码示例、相关图片以及详细的学习笔记,旨在帮助读者深入理解Java中的集合框架 ...

gitblog_06508的博客 606

黑马程序员 Java 面向对象

一 内存图 一个对象的内存图class Student{ private String name = "林青霞"; private int age = 27; public Student(){ name = "刘意"; age = 30; } } 注意,如果调用方法,先在栈中加载,如果调用完毕,就在栈中消失。最终main方法结束,main方法在栈中消失。   二

hn196828828的博客 359

黑马程序员--java中String创建几个对象

---------------------- ASP.Net+Android+IOS开发、.NET培训、期待与您交流! ----------------------

wkf55558963572516的专栏 423

黑马程序员--03.Java面向对象--04.【对象初始化的过程】【对象调用成员的过程】

Java面向对象--4       对象初始化的过程   对象调用成员的过程 ----------- android培训、java培训、java学习型技术博客、期待与您交流! ------------ 给出一段代码: class Person{ private String name; private int age =20; private static Stri

歆明正航的专栏 1468
下一篇: 黑马程序员-java面向对象语法总结
LinsCode
博客等级 码龄13年 2粉丝 12原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值