Java new 背着我们干了什么

Linux下SAP GUI for Java 740安装与连接配置实战指南 在跨平台IT环境中,企业运维与开发人员常面临Windows虚拟机卡顿、远程连接不稳定等痛点。SAP GUI for Java 740作为SAP官方推出的Java客户端,凭借轻量级、跨平台特性,成为Linux和macOS用户连接SAP ECC、S/4HANA等系统的关键工具。其核心原理基于Java运行环境,通过JAR包引导安装,并依赖Java 8的兼容性保证稳定运行。理解组件选择、命令行静默安装、SAProuter配置及中文字体调优等技术细节,能大幅提升日常操作效率。从IT基础运维到业务顾问的日常事务码操作, 阅读详情

new 是 Java 最常用的关键字之一,我们使用 new 创建对象。

我们经常像下面代码一样创建一个对象:

 

Dog dog = new Dog();  

 

只需一行代码,我们就能创建出一只狗,是不是很简单!为什么这么简单?

答:不简单就没人用。

Java 作为面向对象语言,提倡封装,如果自己的语法设计都做不到,那还怎么要求程序员们做到。

创建对象这么常用而且模板化的操作,如果还要写上三四行代码,我想大家都不会乐意。

 

程序员们作为一个没有安全感的群体,经常会为各种事担忧,我们怕技术发展太快会把自己淘汰,我们怕被产品坑,我们更怕新来的领导居然是个产品经理,我们怕面对新人的问题支支吾吾,我们怕PHP居然成了最好的语言,我们怕......

 

好吧,以上都是我自己的担忧。但我要说的是,面对我们唯一可以完全信任的代码,决不允许它背着我干我不知道的事。要知道被自己最信任的人两肋插了两刀,感觉好像PHP真的...... 

 

这个 new 我早就看得不顺眼了,以前还真有人用这个东西把我问得哑口无言。那它在背后到底瞒着我们干了些什么呢?

 

用new这个关键字的话,是调用new指令创建一个对象,然后调用构造方法来初始化这个对象。反编译class的时,你会看到一个 Object obj=new Object(); 这种语句,会先调用new指令生成一个对象,然后调用dup来复制对象的引用,最后调用Object的构造方法。

 

这个过程可以细分为一下几个步骤:

 

1、找它爸,对象和类的一个实例,先有类后有对象,我们通俗把类看作是对象它爸,所以要先找它爸。这个过程就是类加载过程,虚拟机遇到一条new指令时,首先将去检查这个指令的参数(类)是否能在常量池中定位到一个类的符号引用(符号引用是一个字符串,这个字符串包含足够的信息,以供实际使用时可以找到相应的位置),并且检查这个符号引用代表的类是否已被加载、 解析和初始化过。 如果没有,那必须先执行相应的类加载过程。

 

虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验、 转换解析化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的类加载机制。完成了这个过程,就是找到了对象它爸。

 

类从被加载到虚拟机内存中开始,到卸载出内存为止,它的整个生命周期包括:加载(Loading)、 验证(Verification)、 准备(Preparation)、 解析(Resolution)、 初始化(Initialization)、 使用(Using)和卸载(Unloading)7个阶段。 其中验证、 准备、 解析3个部分统称为连接(Linking),这7个阶段的发生顺序如图所示。

 

在加载阶段,虚拟机需要完成以下3件事情:

 

1)通过一个类的全限定名来获取定义此类的二进制字节流。

2)将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构。

3)在内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口。

 

验证是连接阶段的第一步,这一阶段的目的是为了确保Class文件的字节流中包含的信息符合当前虚拟机的要求,并且不会危害虚拟机自身的安全。

验证阶段大致上会完成下面4个阶段的检验动作:文件格式验证、元数据验证、 字节码验证、 符号引用验证。

 

准备阶段是正式为类变量分配内存并设置类变量初始值的阶段,这些变量所使用的内存都将在方法区中进行分配。 这个阶段中有两个容易产生混淆的概念需要强调一下,首先,这时候进行内存分配的仅包括类变量(被static修饰的变量),而不包括实例变量,实例变量将会在对象实例化时随着对象一起分配在Java堆中。 其次,这里所说的初始值“通常情况”下是数据类型的零值。

 

解析阶段是虚拟机将常量池内的符号引用替换为直接引用的过程。

符号引用(Symbolic References):符号引用以一组符号来描述所引用的目标,符号可以是任何形式的字面量,只要使用时能无歧义地定位到目标即可。 

直接引用(Direct References):直接引用可以是直接指向目标的指针、 相对偏移量或是一个能间接定位到目标的句柄。 

 

类初始化阶段是类加载过程的最后一步,前面的类加载过程中,除了在加载阶段用户应用程序可以通过自定义类加载器参与之外,其余动作完全由虚拟机主导和控制。 到了初始化阶段,才真正开始执行类中定义的Java程序代码(或者说是字节码)。

 

把它爸找到后,理想化环境下,我们认为它爸DNA完全遗传给它。所以,在类加载过程中所做的一切都可以认为是为创建对象做准备。对它爸做所的初始化,在创建它时就不用重复进行了。

 

2、选择出生地,我们知道很多国内准妈妈都想尽办法去美国生孩子,这样孩子就是美国公民了,看来出生地也是至关重要啊!我们对象的出生地虽然没有本质上的优劣,但是还是有一个选择的过程。这个选择的过程就是为对象分配内存。在什么地方分配内存也是必须考虑的问题。

 

类加载检查通过后,接下来虚拟机将为新生对象分配内存。 对象所需内存的大小在类加载完成后便可完全确定,为对象分配空间的任务等同于把一块确定大小的内存从Java堆中划分出来。分配的方式有两种:

 

假设Java堆中内存是绝对规整的,所有用过的内存都放在一边,空闲的内存放在另一边,中间放着一个指针作为分界点的指示器,那所分配内存就仅仅是把那个指针向空闲空间那边挪动一段与对象大小相等的距离,这种分配方式称为“指针碰撞”(Bump the Pointer)。

 

如果Java堆中的内存并不是规整的,已使用的内存和空闲的内存相互交错,那就没有办法简单地进行指针碰撞了,虚拟机就必须维护一个列表,记录上哪些内存块是可用的,在分配的时候从列表中找到一块足够大的空间划分给对象实例,并更新列表上的记录,这种分配方式称为“空闲列表”(Free List)。 

 

选择哪种分配方式由Java堆是否规整决定,而Java堆是否规整又由所采用的垃圾收集器是否带有压缩整理功能决定。 因此,在使用Serial、 ParNew等带Compact过程的收集器时,系统采用的分配算法是指针碰撞,而使用CMS这种基于Mark-Sweep算法的收集器时,通常采用空闲列表。

 

3、安全分娩,选好了出生地,它妈就安心养胎了,但时它能不能生下来还要经历最后一关 —— 分娩。这一步至关重要,要是不能确保安全,那就功亏一篑了。这里的安全问题就是线程安全问题。

 

除如何划分可用空间之外,还有另外一个需要考虑的问题是对象创建在虚拟机中是非常频繁的行为,即使是仅仅修改一个指针所指向的位置,在并发情况下也并不是线程安全的,可能出现正在给对象A分配内存,指针还没来得及修改,对象B又同时使用了原来的指针来分配内存的情况。 

 

解决这个问题有两种方案,一种是对分配内存空间的动作进行同步处理 —— 实际上虚拟机采用CAS配上失败重试的方式保证更新操作的原子性;

 

另一种是把内存分配的动作按照线程划分在不同的空间之中进行,即每个线程在Java堆中预先分配一小块内存,称为本地线程分配缓冲(Thread Local Allocation Buffer,TLAB)。哪个线程要分配内存,就在哪个线程的TLAB上分配,只有TLAB用完并分配新的TLAB时,才需要同步锁定。虚拟机是否使用TLAB,可以通过-XX:+/-UseTLAB参数来设定。

 

4、开出生证明,医院会给新生宝宝开出生证明,写上重量、身长、出生时间、性别等信息。

 

这就相当于给对象的实例变量赋初始值,宝宝的重量和身长会在初始值得基础上不断变化,相当于是可变变量。这个初始值可能在以后的生活中不断变化,但是最开始是有一个值的。

 

内存分配完成后,虚拟机需要将分配到的内存空间都初始化为零值(不包括对象头),如果使用TLAB,这一工作过程也可以提前至TLAB分配时进行。 这一步操作保证了对象的实例字段在Java代码中可以不赋初始值就直接使用,程序能访问到这些字段的数据类型所对应的零值。

 

5、上户口,出生以后会给孩子上户口,确定所属的籍贯、名字、家庭等信息。

 

在创建对象时也是一样,虚拟机要对对象进行必要的设置,例如这个对象是哪个类的实例、 如何才能找到类的元数据信息、 对象的哈希码、 对象的GC分代年龄等信息。 

 

这些信息存放在对象的对象头(Object Header)之中。 根据虚拟机当前的运行状态的不同,如是否启用偏向锁等,对象头会有不同的设置方式。 关于对象头的具体内容。

 

在上面工作都完成之后,从虚拟机的视角来看,一个新的对象已经产生了,但从Java程序的视角来看,对象创建才刚刚开始——<init>方法还没有执行,所有的字段都还为零。

 

所以,一般来说(由字节码中是否跟随invokespecial指令所决定),执行new指令之后会接着执行<init>方法,把对象按照程序员的意愿进行初始化,这样一个真正可用的对象才算完全产生出来。

 

所以,new 背着我们生了个孩子 !!!

 

参考:《深入理解Java虚拟机 JVM高级特性与最佳实践》

TransUnet官方代码训练自己数据集(彩色RGB3通道图像的分割) 官方代码:https://github.com/Beckschen/TransUNet 目的:训练5个类别的汽车部件分割任务(测试在另一篇博客中) 实现效果: 1. github下载代码,并解压。 项目里的文件可能跟你下载的不一样,不急后面会讲到! 2. 配置数据集(尽最大努力还原官方数据集的格式)。 通常自己手上的数据集分images和labels文件夹,分别存放着原始图像和对应的mask图像,如下图所示; mask图像中的像素有0,1,2,3,4 分别代表背景,车身,轮子,车灯,窗户,一共五个 阅读详情

相关推荐

单相全桥逆变三种SPWM调制方式(单极/双极/倍频)到底怎么选?一篇讲透优缺点与选型

本文深入解析单相全桥逆变器中单极性、双极性和单极性倍频三种SPWM调制方式的原理与工程选型策略。通过对比开关损耗、谐波特性和驱动复杂度等关键指标,提供基于STM32的实战方案和选型框架,帮助工程师在新能源发电、电机驱动等应用中做出最优决策。

weixin_34046298的博客 798

学习笔记——new关键字在底层究竟做了什么

new关键字(操作符)在底层究竟做了什么?

qq_41339126的博客 691

【一步到位】Android Studio 实现安卓连接阿里云物联网云平台

最新版本目前是Android Studio Iguana | 2024.1.2,你可以到官网上去找之前的版本,手上有工作项目的不要去轻易尝试,说不定你就编译失败了,失败了也不要担心,解决就可以了。

m0_73799445的博客 1万+

new一个对象,java虚拟机做了什么?

这个问题一直困扰我很久,面试被问到好多次,但是都没有一个清晰的认识,然后最近在回头过来看下java基础回味下。 当刚写完一个java程序,main方法new一个对象,内存做了如下操作:  一、初期:  程序先进入编译时期,java编译器将程序代码编译成字节码信息; 二、中期—类加载和类连接 2.1类加载:首先通过类加载器将类class文件,加载到内存方法区,并创建java.lang.clas...

bingguang1993的博客 460

OAK-D-Pro深度解析:从硬件融合到全天候SLAM实战

本文深度解析OAK-D-Pro硬件架构及其在SLAM领域的实战应用。作为SLAM的"六边形战士",OAK-D-Pro融合主动双目摄像头、结构光投射器、6轴IMU等传感器,实现全天候稳定工作。通过实测数据展示其在弱纹理环境、动态光照等复杂场景下的卓越表现,并提供SLAM实战技巧与开发指南,帮助开发者快速部署高效SLAM解决方案。

weixin_27244795的博客 183

【AI之路】cmd命令行通过Huggingface镜像站快速下载模型文件的方法

Hugging Face Hub 是分享机器学习模型、演示、数据集和指标的首选之地。huggingface_hub 库可以轻松下载Huggingface上有用的模型和数据集元数据。但大模型文件通常较大,国内下载太慢,那有没有高效便捷的方法?这个当然必须有!看到了吗?只是添加一个参数,下载大模型就搞定了。当然也可以使用python程序来下载。具体见前期博文:【AI之路】使用huggingface_hub通过huggingface镜像站hf-mirror.com下载大模型(附代码,实现大模型自由)

IT里的交易员-博客 1848

Java里的new

java里的new的英文意思就是"新的"的意思。在JAVA里就是创建一个新的实例,或者说一个新的对象,一个普通类在没有实例化之前,就是new之前,它的属性,方法等等在内存中都是不存在的。只有使用new了以后,这个类的一些东西在内存中才会真的存在,也就是说只有new了之后,这个类才能用。 举例说明: Java中使用 new关键字 加上 构造方法,来创建一个对象,下面是一个名为Cat的类,public...

Jason的学习笔记 2万+

实例讲解Simulink应用层开发CAN报文解包及CAN信号设置方法

本文通过讲解MCU CAN解包模块的模块设置、输入输出信号的设置及仿真测试验证,说明了CAN解包模块的设置方法、CAN解包模块输入输出信号的设置方法以及CAN解包模块的仿真测试及修正方法。在模型搭建过程中,建议养成一种搭建完成仿真测试验证的习惯,在模块阶段发现错误,解决错误,避免在后期模块集成之后报出大量错误,增加解决错误的工作量和难度。希望通过本文的介绍能给相关技术人员带来一些参考和帮助。

qq_43011586的博客 5679

java 如何理解new_JAVA中new的 理解

T1 a= new T1();T2 b= new T1(); 区别:问题1:不是实例化一个a,是实例化一个T1T1 的一个 对象的引用 a 指向了堆空间里的一个新T1对象 ------------------------------------------new是java里面的关键字.一般用于创建一个新的对象.T1 a= new T1();表示创建一个新的T1对象.T2 b= new T1();...

weixin_32021519的博客 5157

Avalonia+ReactiveUI跨平台路由:从零到舞者,你的UI也能跨界起舞?

至此,你已掌握了Avalonia+ReactiveUI的跨平台路由精髓!你的应用现在能够优雅地在各个界面间穿梭,就像是在不同星球间跳跃的宇宙飞船。无论是初探跨平台开发的新手,还是经验丰富的老船长,这段旅程都能让你的UI编排技能更上一层楼。现在,是时候让世界见证你的跨平台魔术了!💫记住,每一次实践都是向着完美编舞迈进的一步,勇敢地在你的项目中尝试吧!如果在航行中遇到风暴,别忘了回来看看这篇指南,或者在评论区抛出你的救生圈,我们一起解决!🌊。

java专栏 1534

Windows Server 2019 服务器一天之中内存利用率越来越高直到死机,疑似内存泄漏

环境: 华为桌面云虚拟机 Windows Server 2019 版本1809 OS内部版本17763.107 问题描述: Windows Server 2019服务器 一天之中内存利用率越来越高直到死机,不断扩容内存从10G到16G一重启就正常然后慢慢又循环,连续几天都这样,疑似内存泄漏 内存泄漏是什么? 内存泄漏指由于疏忽或错误造成程序未能释放已经不再使用的内存。内存泄漏并非指内存在物理上的消失,而是应用程序分配某段内存后,由于设计错误,导致在释放该段内存之前就失去了对该段内存的控制,从而造成了内存的浪

本博客,博文仅代表个人操作经验,不能完全解决你的问题,仅供参考,佛系回复。 5392

JAVA基础- new一个对象的原理和过程

最新的 Java 面试题,技术栈涉及 Java 基础、集合、多线程、Mysql、分布式、Spring全家桶、MyBatis、Dubbo、缓存、消息队列、Linux…等等,会持续更新。

qq_42872034的博客 1万+

高通开发系列 - Bootloader之lk匹配dtb和dtbo中msm-id和board-id的知识

lk匹配dtb和dtbo中的msm-id和board-id等知识

fulinux的博客 4244

Java创建对象和spring创建对象的过程和区别

理解两种创建方式的本质差异,我们可以:在传统单体架构中合理选择对象管理方式在微服务架构中优化Bean初始化顺序在云原生环境下平衡启动速度与便利性深度定制Spring容器满足特殊需求。

m0_75236543的博客 1038

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

从零开始的Java学习笔记(一):Java的变量,对象,和引用

1. 关于java“变量“      在java语言中,一切皆是对象(objects),当然所谓“变量”也不例外。通常情况下来讲,当提到”变量”(varibles)这个词的时候,一般指的都是基本类型(primitive types),也被称作内置类型,它是JAVA中不同于普通类的特殊类型(之后简称变量)。

c_Namya的博客 389

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

JAVA基础(一)----对象

很多人对程序猿的固定印象就是:永远背着电脑、万年不变的格子衫、随时可以黑进你的电脑……并且能整天对着电脑码一些大家都看不懂的东西。       这大概都是被各种影视电影影响,程序猿的工作好像都是些高大上的东西,普通人不明白其中的奥妙也掌握不了其中的乐趣,现在我就带领大家揭开程序员生活的神秘面纱。       既然程序猿是“猿类”,那么,他们之间该如何交流呢?像法国人用的是法语,英国人用

tanglixing的博客 270

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

Java面试核心知识点与实战技巧解析

Java作为企业级开发的主流语言,其核心技术体系涵盖JVM内存模型、多线程并发编程、集合框架等核心模块。理解进程与线程的本质区别需要从操作系统层面分析资源隔离与共享机制,而JUC工具包则提供了线程池、同步器等高效并发解决方案。在分布式系统架构中,Spring Boot的自动配置原理和MyBatis的SQL优化技巧直接影响系统性能,HashMap的扩容算法和JVM垃圾回收策略更是面试高频考点。掌握这些技术不仅需要通过源码理解设计思想,更要结合电商秒杀、订单处理等实际业务场景进行工程实践,这正是腾讯、阿里等大厂

weixin_30521161的博客 403

java swing ejb_为什么要使用EJB

首先,我们必须明确,为什么要使用J2EE?J2EE优点是什么?使用J2EE的主要原因是多层结构,传统的两层C/S结构难于维护,稳定性极差,界面代码和数据库代码混淆在一起,牵一动百,多层结构使得界面和数据库完全分离,并且诞生了中间件这样的技术,如下图:Web+EJB能组成真正的多层结构为什么使用EJB我原先认为这不是一个讨论的话题,因为EJB是J2EE重要的组成部分,可以说没有EJB的J2EE只是一...

weixin_39889337的博客 175

面试官:你说你精通Java?谢飞机:那当然了,我写了三年CRUD![特殊字符]

详细答案:JDK 1.7的致命问题——环形链表在JDK 1.7中,HashMap扩容时使用头插法转移链表。多线程同时扩容时,可能导致链表形成环形结构,后续get()操作会陷入死循环,CPU 100%。// JDK 1.7 transfer方法(简化)while (e!= null) {// 多线程下这里可能出问题// 头插法e = next;JDK 1.8的数据覆盖问题JDK 1.8改用尾插法解决了环形链表问题,但put操作不是原子的// 两个线程同时put,可能会互相覆盖数据。

qq_45952553的博客 380

严肃面试官 vs 搞笑谢飞机:大厂 Java 三轮面试实录(含详解)

场景:互联网大厂面试间。面试官黑着脸坐在对面,候选人“谢飞机”笑嘻嘻坐下,还不忘把保温杯往桌上一放。——开始!

weixin_46755643的博客 383

什么!少年你居然以为this关键字很简单?还不看我博客?

This关键字 屏幕前的少年你,也许看见我的这篇博客会不禁嘴角一笑:呵呵了,this关键字还不简单?如果你是大佬请装作没看见这篇博客,千万别点赞啊!(疯狂暗示)……如果你还在学习java语法,也许你学过this,但也别走,真的真的真的,我的这篇博客真的会让你对this有个更加深刻的理解。(如果觉得nice的话,一定要点个赞再走啊,别白嫖啊!)

qq_44230254的博客 192

Java系统分析/架构师欢迎大家关注我的公众号

【专业知识相关】 谈谈对OOP、IOC、AOP的设计理念的理解; (1)ioc,意思是Inversion of control,(反转控制),控制反转,就是交换控制权的意思。现在一般不使用这个词,一般使用dependency injection(依赖注入)。依赖注入就是将依赖 注入进去。(2)这么来说吧,在一个动作或者事件中,比如说,你现在想写字(Action),那么你需要笔,于是乎,你ne...

剑雪封喉 362

OneAPM 云监控部署与试用体验

作为 Zabbix 骨灰级粉丝,一直以来对第三方监控(APM)都是拒绝的。一来觉得收费,二来担心数据被人所知,三来觉得 Zabbix 牛逼到无可取代。但是,随着 APM 市场的火爆,我决定「放下身段」试用一次,并且会总结出它与开源监控之间差别在哪里。运维经历的磨难虽然都在不同的公司,做着不同的业务,但是大多运维总会经历相同的故事,以及背着类似的黑锅。运维们大多有如下经历:

wangpeng198688的专栏 2113

[APM] OneAPM 云监控部署与试用体验

摘要: 作为 Zabbix 骨灰级粉丝,一直以来对第三方监控(APM)都是拒绝的。一来觉得收费,二来担心数据被人所知,三来觉得 Zabbix 牛逼到无可取代。但是,随着 APM 市场的火爆,我决定「放下身段」试用一次,并且会总结出它与开源监控之间差别在哪里。 作为 Zabbix 骨灰级粉丝,一直以来对第三方监控(APM)都是拒绝的。一来觉得收费,二来担心数据被人所知,三来觉得 Zabbi...

weixin_34220963的博客 371

为什么要使用EJB?

首先,我们必须明确,为什么要使用J2EE?J2EE优点是什么?使用J2EE的主要原因是多层结构,传统的两层C/S结构难于维护,稳定性极差,界面代码和数据库代码混淆在一起,牵一动百,多层结构使得界面和数据库完全分离,并且诞生了中间件这样的技术,如下图: Web+EJB能组成真正的多层结构   为什么使用EJB我原先认为这不是一个讨论的话题,因为EJB是J2EE重要的组成部分,可以说没有EJB

xyjikl 721
上一篇: 【单例深思】枚举实现单例原理
下一篇: LeetCode 39. Combination Sum 题解
TaiSung
博客等级 码龄15年 49粉丝 132原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值