要单独将一个处理器类导出为 jar 包,除了用 Eclipse,用 jar 命令和 maven 打包也是很方便的。本文介绍了导出 Jar 包的几种方式。
JVM 07 对象的实例化内存布局与访问定位
对象的实例化
对象实例化的几种方式
美团:
- 对象在 JVM 中饭是怎么存储的?
- 对象头信息里面有哪些东西?
蚂蚁金服:
- 二面:Java 对象头里有什么?
对象的实例化:
- 创建对象的方式
newnew最常见的方式- 变形 1 : Xxx 的静态方法
- 变形 2 : XxxBuilder/XxxFactory 的静态方法
- Class 的
newInstance()- 反射的方式,只能调用空参的构造器,权限必须是
public
- 反射的方式,只能调用空参的构造器,权限必须是
- Constructor 的
newInstance(Xxx)- 反射的方式,可以调用空参、带参的构造器。权限没有要求
- 使用
clone()- 不调用任何构造器,当前类需要实现
Cloneable接口, 实现clone()
- 不调用任何构造器,当前类需要实现
- 使用反序列化
- 从文件、网络中获取一个对象的二进制流
- 第三方库
Objenesis
- 创建对象的步骤
- 判断对象对应的类是否加载、链接、初始化
虚拟机遇到一条new指令 ,首先去检查这个指令的参数能否在 Metaspace 的常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否已经被加载、解忻和初始化。( 即判断类元信息是否存在)。如果没有,那么在双亲委派模式下,使用当前类加载器以ClassLoader+包名+类名为 Key 进行查找对应的 .class 文件。如果没有找到文件,则抛出ClassNotFoundException异常,如果找到,则进行类加载,并生成对应的Class类对象 - 为对象分配内存
首先计算对象占用空间大小,接着在堆中划分一块内存给新对象。如果实例成员变量是引用变量,仅分配引用变量空间即可,即4个字节大小。- 如果内存规整
- 指针碰撞
- 如果内存不规整
- 虚拟机需要维护一个列表
- 空闲列表分配
- 说明
- 如果内存规整
- 处理并发安全问题
- 采用 CAS 配上失败重试保证更新的原子性
- 每个线程预先分配一块 TLAB
- 初始化分配到的空间
- 所有属性设置默认值,保证对象实例字段在不赋值时可以直接使用
- 设置对象的对象头
- 执行
init方法进行初始化
- 判断对象对应的类是否加载、链接、初始化
从字节码角度看对象的创建过程
对象的内存布局
对象的访问定位
JVM 06 运行时数据区的总结与常见大厂面试题说明
常见面试题
JVM 05 运行时数据区之方法区 (MethodArea)
JVM 04 运行时数据区之堆 (Heap)
1 堆的核心概述
- ● 一个 JVM 实例只存在一个堆内存,堆也是 Java 内存管理的核心区域。
- ● Java 堆区在 JVM 启动的时候即被创建,其空间大小也就确定了。是 JVM 管理的最大一块内存空间。
- ➢ 堆内存的大小是可以调节的。
- ● 《Java 虚拟机规范》规定,堆可以处于物理上不连续的内存空间中,但在逻辑上它应该被视为连续的。
- ● 所有的线程共享 Java 堆,在这里还可以划分线程私有的缓冲区 (ThreadLocal Allocation Buffer, TLAB)
一个 JVM 实例对应一个进程,方法区和堆是一个进程一份,而程序计数器、本地方法栈、虚拟机栈是一个线程对应一份,一个进程中的所有线程共享方法区和堆(并不是完整的堆都一定是共享的,比如 TLAB)。
JVM 03 运行时数据区之虚拟机栈 (Stack)
- 1 虚拟机栈概述
- 2 栈的存储单位
- 3 局部变量表
- 4 操作数栈
- 5 代码追踪
- 6 栈顶缓存技术
- 7 动态链接
- 8 方法的调用:解析与分派
- 9 方法返回地址
- 10 一些附加信息
- 11 栈的相关面试题
JVM 02 运行时数据区概述及线程、程序计数器
JVM 01 类加载器及类加载过程
Hadoop Mapreduce作业执行过程中报错 this version of the Java Runtime only recognizes class file versions up to 52.0
该错误告诉我们,我们的类是在比尝试运行它的版本更高的Java版本下编译的。 更具体地说,在这种情况下,我们使用Java 11编译了我们的类,并尝试使用Java 8运行它。
8088端口能打开但是打不开hadoop job history Tracking UI和日志Logs等页面
问题描述:
通过http://ip:8088/能够访问All Applications页面,但是在执行一个application完之后,通过网页中的Tracking UI -> History链接跳转到http://localhost:8088/proxy/application_..._0001/jobhistory/job/job_..._0001,http://localhost:19888/jobhistory页面。但是因为Hadoop服务器是部署在公网的,而8088端口的管理界面中的jobhistory链接和Logs链接、Node链接中的主机名(hostname)都是 localhost 而不是服务器的公网ip地址。
而且查看Mapreduce执行时终端的日志信息有这么一句:INFO mapreduce.Job: The url to track the job: http://localhost:8088/proxy/application_..._0001/
这说明了jobtracker服务的url地址是服务器本地主机,并不是公网ip,所以job tracker url没能正确被生成。
解决方法:
在NameNode节点的服务器上执行netstat -nltp | grep LISTEN命令之后发现几个重要端口如8088、8042等服务监听都正常,试着手动将浏览器url地址中的localhost改成服务器的公网ip地址,发现是能够打开Logs和Job History等页面的。所以推测是在生成jobtracker url的时候将hostname设置成了localhost。
解决步骤: 在修改了$HADOOP_HOME/etc/hadoop/mapred-site.xml 和 $HADOOP_HOME/etc/hadoop/yarn-site.xml 两个配置文件中的几处address hostname为服务器的公网ip或者域名之后就正常了。注意:不能填0.0.0.0!
- $HADOOP_HOME/etc/hadoop/mapred-site.xml
1 | <configuration> |
- $HADOOP_HOME/etc/hadoop/yarn-site.xml
1 | <configuration> |
修改完这两个配置文件之后重启HDFS和YARN服务,再次用hadoop jar执行一个application:INFO mapreduce.Job: The url to track the job: http://23.105.206.170.16clouds.com:8088/proxy/application_1593439350379_0001/
终端输出的日志信息中的jobtracker url从localhost变成了服务器的ip地址或者域名,此时应该就正常了。再次浏览器打开8088 applications页面,发现网页中的所有超链接都正常指向了公网ip或域名。
默认配置项及配置项说明文件: