Go Runtime vs JVM:调度、GC、反射全方位对比

Go 运行时 vs JVM 运行时 一个 JVM 调优经验丰富的开发者第一次部署 Go 服务,看到监控数据时的反应: 这进程怎么只占 4MB? -Xmx 在哪设置?GC 日志怎么看? 接着打开 top ,看到 Go 服务起了几千个 goroutine,内存和 CPU 都低得离谱。而旁边跑了类似流量的 Spring Boot 服务, -Xmx512m 、GC 日志一大堆。 这不是魔法,是 Go runtime 和 JVM 的设计哲学完全不同。本文把两个运行时的核心差异讲清楚。 📌 前置知识:本文假定读者了解 JVM 的基本运行时概念(堆/栈/GC/类加载/JIT)和 Go 的 goroutine 基础知识。Go 版本为 1.22,对比 JVM HotSpot 17/21。 进程内存:4MB vs 512MB 的真相 维度 Go JVM(HotSpot) 最小内存 ~2-4MB ~50-200MB(含堆 + 元空间) 内存控制 自动,GOGC 环境变量 -Xmx / -Xms + 大量 JVM 参数 启动时间 毫秒级(AOT 编译) 秒级(类加载 + 解释执行 + JIT 预热) 部署产物 单一静态二进制(~10-20MB) JAR(需要 JRE/JDK 运行时) 内存占用大头 goroutine 栈 + 堆 + GC 元数据 堆 + 类元数据 + JIT 代码缓存 + 线程栈 两张图看清两个运行时各自的内存里到底装了什么: ...

二月 10, 2023 · 7 分钟 · 1322 字 · yaomingye

Go Web 开发全栈:从 Gin 到微服务

Go Web 开发:从 Gin 到微服务 一个 Spring Boot 程序员打开 Go 的 Web 项目,看到的是这样的代码: // 这是什么?Controller 在哪?@Autowired 在哪? func main() { db, _ := sql.Open("mysql", "user:pass@/dbname") repo := NewUserRepo(db) svc := NewUserService(repo) handler := NewUserHandler(svc) r := gin.Default() r.GET("/users/:id", handler.GetUser) r.Run(":8080") } 没有 @Controller 、没有 @Service 、没有 @Autowired 、没有 application.yml 。依赖是一个个手动拼起来的,路由是函数式注册的,连配置文件都得自己选库来读。 习惯 Spring Boot 全家桶的开发者,第一次面对 Go 的 Web 生态,大概有两类困惑: 框架选型:Gin、Echo、Fiber、Iris、go-zero、Kratos……每个都说自己性能好,到底该用哪个? 组织方式:没有注解驱动的 DI、没有 AOP、没有 Filter 接口——同样的需求在 Go 里怎么写? 本文用 Spring Boot/Spring Cloud 的对应视角,把 Go Web 开发的技术栈讲清楚。 ...

二月 8, 2023 · 9 分钟 · 1846 字 · yaomingye

Go 网络编程与 IO 模型

Go 网络编程 Java 程序员写网络服务,技术栈大概是这样的: // Java —— Netty 写一个 HTTP 服务 EventLoopGroup bossGroup = new NioEventLoopGroup(1); EventLoopGroup workerGroup = new NioEventLoopGroup(); try { ServerBootstrap b = new ServerBootstrap(); b.group(bossGroup, workerGroup) .channel(NioServerSocketChannel.class) .childHandler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel ch) { ch.pipeline() .addLast(new HttpServerCodec()) .addLast(new HttpObjectAggregator(65536)) .addLast(new SimpleChannelInboundHandler<FullHttpRequest>() { @Override protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest req) { // 业务逻辑... } }); } }); b.bind(8080).sync().channel().closeFuture().sync(); } finally { bossGroup.shutdownGracefully(); workerGroup.shutdownGracefully(); } 配置 EventLoopGroup、Channel Pipeline、Codec、Handler……对于一个简单的 HTTP 服务,一半代码在处理 Netty 的样板。 ...

二月 6, 2023 · 5 分钟 · 1011 字 · yaomingye

Go 并发编程:Goroutine、Channel 与 CSP 模型

Go 并发编程 写了 5 年 Java 并发,你手上的工具大概是这样的: // Java —— 线程池 + Future + BlockingQueue var executor = Executors.newFixedThreadPool(10); var future = executor.submit(() -> { return remoteService.query(); }); try { var result = future.get(5, TimeUnit.SECONDS); } catch (TimeoutException e) { future.cancel(true); } 现在看 Go 的等价写法: // Go —— goroutine + channel + select func queryWithTimeout() { ch := make(chan string, 1) go func() { ch <- remoteService.Query() }() select { case result := <-ch: fmt.Println(result) case <-time.After(5 * time.Second): fmt.Println("超时了") } } 没有 Executor ,没有 Future ,没有 BlockingQueue 。 go 关键字一写,协程就启动了。 chan 一建,数据就在协程间流动。 这是 Go 语言最独特的基因 。 ...

二月 4, 2023 · 7 分钟 · 1383 字 · yaomingye

Java vs Go 语法快速对比

Java vs Go:语法对比 打开 .go 文件,第一眼看到这些,脑子直接宕机: func getUser(id int) (*User, error) { if user, ok := cache.Load(id); ok { return user.(*User), nil } defer func() { metrics.Record("getUser") }() // ... } := 是什么? *User 和 error 为什么挤在返回值里? defer 又是什么鬼? ok 从哪冒出来的? 写了 5 年 Spring Boot,习惯了 var user = new User() 、 try-catch-finally 、 public class 之后,Go 的语法看起来像是故意反着来。这篇文章的目的就是一句话:把所有 Java 里习以为常的语法点,在 Go 里找到对应写法 。没有废话,全是代码对比。 📌 前置知识:本文假定读者有 Java 基础(Java 8+),了解基本的编程概念(变量、函数、循环、异常)。Go 版本为 1.22。 ...

二月 2, 2023 · 10 分钟 · 1994 字 · yaomingye

Go 语言历史与设计哲学

Go 是怎么来的? 第一次打开 .go 文件的 Java 程序员,通常会愣住。 type Handler struct { db *sql.DB } func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { users, err := h.queryUsers(r.Context()) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } json.NewEncoder(w).Encode(users) } 脑子里弹出一串问题:class 在哪?构造函数在哪?try-catch 在哪?implements 在哪?为什么 err 是个返回值? 这很正常。写了 5 年 Spring Boot,习惯了 @Autowired 、 @Transactional 、 try-catch-finally 之后,Go 看起来像删掉了 90% 语法的 Java。但这不是残缺,是刻意的——Go 的设计哲学就是 少即是多 。 诞生:三个大佬对 C++ 的"不满" 2007 年,Google 的三个工程师——Robert Griesemer(Google V8 引擎参与者)、 Rob Pike(Unix 元老,Plan 9 作者)、 Ken Thompson(Unix 之父,B 语言/C 语言设计者)——在等 C++ 编译的时候,决定搞点事情。 ...

一月 31, 2023 · 5 分钟 · 902 字 · yaomingye
Cat Radio