云原生时代的Java
所属分类 architecture
浏览量 1023
一次编写,到处运行 Write Once, Run Anywhere
跨平台 JAVA 语言层虚拟化 JVM
不同平台下内存模型、线程模型、字节序等
托管语言(Managed Language,如Java .NET )
云原生选择以操作系统层虚拟化的方式
将程序连同运行环境一起封装到稳定的镜像里,已是一种主流的应用程序分发方式
Docker 一次构建,到处运行 (Build Once, Run Anywhere)
削弱了java 跨平台的优势
微服务
镜像体积、内存消耗、启动速度
JVM资源消耗
原生语言(Native Language,如Golang Rust)
将字节码直接编译成可以脱离JVM的原生代码
GCJ(GNU Compiler for Java)
Excelsior JET
2018年Oracle Labs启动的GraalVM中的SubstrateVM模块
2020年刚建立的Leyden项目,朝着提前编译(Ahead-of-Time Compilation,AOT)生成原生程序这个目标迈进
云原生编译 GraalVM
Java支持提前编译最大的困难在于它是一门动态链接的语言,
它假设程序的代码空间是开放的(Open World),
允许在程序的任何时候通过类加载器去加载新的类,作为程序的一部分运行。
要进行提前编译,就必须放弃这部分动态性,假设程序的代码空间是封闭的(Closed World),
所有要运行的代码都必须在编译期全部可知。
这一点不仅仅影响到了类加载器的正常运作,除了无法再动态加载外,
反射(通过反射可以调用在编译期不可知的方法)、动态代理、字节码生成库(如CGLib)等一切会运行时产生新代码的功能都不再可用,
如果将这些基础能力直接抽离掉,Helloworld还是能跑起来,但Spring肯定跑不起来,Hibernate也跑不起来,
大部分的生产力工具都跑不起来,整个Java生态中绝大多数上层建筑都会轰然崩塌。
从Spring Framework 5.2开始增加了@proxyBeanMethods注解来排除对CGLib的依赖,仅使用标准的动态代理去增强类
Java 一切皆为对象 ,导致在处理一系列不同类型的小对象时,内存访问效率低
Valhalla项目
从JDK 6起,HotSpot的即时编译器就尝试通过逃逸分析来做标量替换(Scalar Replacement)和栈上分配(Stack Allocations)优化,
基本原理是如果能通过分析,得知一个对象不会传递到方法之外,那就不需要真实地在对中创建完整的对象布局,
完全可以绕过对象标识符,将它拆散为基本的原生数据类型来创建,甚至是直接在栈内存中分配空间(HotSpot并没有这样做),
方法执行完毕后随着栈帧一起销毁掉。
逃逸分析是一种过程间优化(Interprocedural Optimization),非常耗时,也很难处理那些理论有可能但实际不存在的情况
值类型支持
不支持原数据类型(Primitive Type) 频繁装箱问题
Project Loom
让Java支持额外的N:M线程模型
支持结构化并发(Structured Concurrency)
Loom简化并发编程的核心理念 Code like sync,Work like async
Portola项目
将OpenJDK向Alpine Linux移植
Alpine Linux是许多Docker容器首选的基础镜像,因为它只有5 MB大小
上一篇
下一篇
Kafka网络模型
java nio 编程模型简介
kafka Coordinator 简介
进程io监控命令iopp
Stack ArrayDeque LinkedList
java线程状态及转换