首页   注册   登录
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
拉钩
V2EX  ›  Java

现在 Java 界推崇“use Jar, not War”,但是这 Jar 的内存占用也太。。。。。。

  •  1
     
  •   abcbuzhiming · 7 天前 · 4129 次点击
    以前我们部署 Java 的 Web 应用,都是搞个 Tomcat 或者 Jetty 这样的 Servlet 容器服务器装到到目标机器,然后每个应用 App 在 Servlet 容器服务器占据一个上下文路径来提供自己的服务。这样的服务器启动时占的内存不大,也就 1GB 左右,但是内部的应用会互相干扰抢占资源占用,有的时候一个应用出现了无法卸载的死机,你会不得不把整个 Servlet 容器服务器停下来。最近的 Java 界,大家都推崇直接用 Jar 包跑,反正 jar 包里有内嵌的 Servlet 容器服务器。好处就是各个 Jar 之间可以互不干扰了,但是这启动内存占用真是吓人,1 个启动的时候都接近 1G 了,一台服务器上启动几个 Jar,内存就要没了。我想了想,这应该还是 Servlet 容器服务器的锅,内嵌的容器服务器那也是服务器啊。所以我想问问各位:
    1.你们这么看待和解决这个问题?
    2.业界最近有干脆去掉 Servlet,用别的方式提供 Web 服务的声音,而且确实出现了这样的框架,有人实践过吗,有好处吗?资源占用情况如何
    43 回复  |  直到 2018-12-07 16:08:52 +08:00
        1
    jjianwen68   7 天前
    启动占用 1g 不是 jar 本身占用吧,是服务本身加载的 cache 吧
        2
    zjsxwc   7 天前
    加 swap 文件分区就行
        3
    sagaxu   7 天前 via Android
    springboot 内嵌 tomcat 启动,自身占用内存不到 50M,1g 至少能启动 8 个 app。
        4
    lovelybear   7 天前
    所以还是用 war
        5
    sagaxu   7 天前 via Android
    @zjsxwc fullgc 遇到 swap 就是找死
        6
    xiaoyunwei2   7 天前
    总有人想搞点新花样出来
        7
    misaka19000   7 天前 via Android   ♥ 2
    问题在于为什么要在一台负载上面启动多个 jar 进程呢
        8
    abcbuzhiming   7 天前
    @jjianwen68 服务本身没有加什么 cache,就是表有点多,50 个表左右,各种 Service,mapper 文件,Controller 也不少
        9
    peyppicp   7 天前
    Servlet 容器占不了多少资源。对响应没那么高的应用,可以少开点线程。加个-Xmx2g 啥的参数控制一下吧
        10
    jorneyr   7 天前
    用经典的 Tomcat 部署, 多个 Web 可以把都有的 jar 包放到 Tomcat 的共享 lib 里, 不需要每个应用都各自加载一次这些 jar 包, 这样可以省掉不少资源.
        11
    abcbuzhiming   7 天前
    @sagaxu 你的 spring boot 怕不是空项目吧?你加上各种 Controller,Service,Mapper,各种逻辑类,还有 Web 模板,静态资源,然后再看看。
        12
    abcbuzhiming   7 天前
    @misaka19000 你一定是在大公司,有海量的服务器给你用,中小型公司哪家服务器上就跑一个 jar 的?
        13
    mmdsun   7 天前 via Android
    说下是什么命里如何查询 jar 占用内存的?是不是有误差。我这边最多 500M
        14
    boris1993   7 天前 via Android
    @abcbuzhiming #12 裸铁上装 ESXi 啊,然后一个应用开一个虚拟机,资源按需分配,一台虚拟机只跑一个 war 或者 jar
    我司就是这个套路,也没有海量服务器,真铁只有个位数,上面跑了一麻袋虚拟机
        15
    sagaxu   7 天前 via Android
    @abcbuzhiming 各种 Controller,Service,Mapper,各种逻辑类,还有 Web 模板,静态资源

    这些东西分开也好独立也好,占用的内存是一样多的,没有被共享的,不就是空项目的那部分开销吗?
        16
    tnt666666   7 天前 via Android
    推崇??去他吗的推崇
        17
    aa6563679   7 天前 via iPhone
    没那么夸张,一个 jar 服务空闲时 gc 后也就占不到 100m。
        18
    szq8014   7 天前
    @abcbuzhiming 富应用的话 1G 内存不多吧 0。0
        19
    apeshit   7 天前
    遇到这种多个 web services 需要在同一台机器上运行的情况, 为了可靠性和可扩展性, 为什么不使用 kubernetes + docker 的架构? 每个 web service 在自己的容器里面, 可以 configure 每个 service 的资源, replica 和 failover 策略
        20
    abcbuzhiming   7 天前
    @mmdsun 我这边是在 windows 发现问题的,windows server 2012R2,任务管理器里,Java Platform SE binary 占用内存 9xx.xxMB。。。
    看了你们说的,我现在也在分析是不是我打开 spring boot 的姿势不太对,这个内存占用貌似有点不太正常的样子
        21
    msg7086   7 天前   ♥ 3
    @abcbuzhiming #12
    反过来说。没有钱上多台服务器或者高配服务器的,为什么要去用 Java 呢。
    就像以前用 Oracle 的,十年前大家都在说,Oracle 一开,几十 G 内存就没了。那时候 48G 内存的至强都是要有点矿才能买得起了。那所以小公司没人去搞 Oracle 啊。一样的道理。
    Java 的本来设计得就是用大内存换取高性能,买不起内存是你公司的事,你想想不充钱能变强吗(笑)
        22
    passerbytiny   7 天前   ♥ 4
    请善用 Xms、Xmx 参数。如果你的程序小,那么请使用 java -Xms32m -Xmx64m -jar some.jar 来启动。不加参数,5 个 java 进程就能占满内存。
        23
    q397064399   7 天前
    加钱买内存,内存真的很便宜,随便一个程序员的一年的工资 都能买差不多 2T 的服务器内存了。
    买服务器内存的钱都没有,你搞什么 Java?
        24
    Cbdy   7 天前
    可以不基于 Servlet 做,用 Netty:比如 Vert.x、Spring Web Flux,当然做出来的东西也是 Jar
        25
    bdnet   7 天前
    简单来说,单独一个 JVM 实例隔离型好于共享,各有优缺,脱离场景,没有那个一定好

    不过,现在一个手机内存都 8G 内存了
        26
    HiJackXD   7 天前 via iPhone
    可以用用 playframework1.x 之类的不依赖 servlet 容器的框架 速度和开发体验都比 ssm 好多了
        27
    qiyuey   7 天前
    一台机器只部署一个 Jar,目前主流的方法是 Docker + Jar
        28
    liuxey   7 天前
    我觉得最终云化后就变得像 Google Cloud Function 和 Amazon 的 lambda,不仅把 tomcat 抽象化,servlet 也抽象化,最终面向 Function 编程。

    所以期待 springboot 再次进化,变成一个纯 Serverless 的平台,开发人员面向 Lambda 编程,部署的只是一个一个 lambda,再加入一些可公共调用的 lambda API,完美~
        29
    mmdsun   6 天前 via Android
    @abcbuzhiming 那算总的。启动 jar 前电脑内存,启动 jar 后电脑内存,两个一减。
        30
    mgcnrx11   6 天前 via iPhone
    Xms 堆参数啊,每个机器内存都不同,这样谈占用有什么意义
        31
    Cbdy   6 天前 via Android
    @liuxey 已经有了,Spring Cloud Function 了解一下
    http://cloud.spring.io/spring-cloud-function/
        32
    Mohanson   6 天前
    golang 4000 万请求每日, 常年 20 M 内存, 考虑一下(狗头
        33
    liuxey   6 天前
    @Cbdy #31 这个之前也了解过了,但是还是太粗糙,只是将传统 controller 稍微封装了下,默认 method -> URI 的映射规则,等以后发展看看会变成什么样吧。
        34
    Cellei   6 天前
    抽时间试一下 vert.x
        35
    wdlth   6 天前
    不用 Undertow 么?
        36
    donyee   6 天前
    要榨取性能的话,就不推荐使用 java servlet 这些框架;
    1 个应用都不愿意分配 1G 内存,那么是不是你们这些应用功能比较单一、用户量太小
    搞不懂这些...
        37
    loveCoding   6 天前
    上线前压测下 , 找到合理的-Xms -Xmx ,不要啥都不管直接开始跑
        38
    Vamposine   6 天前 via iPhone
    @abcbuzhiming 如果是生产环境,一个服务器上就独立放一个 service 才是正解,如果物理服务器个数不够,可以虚拟化,做好资源隔离就好
        39
    TinyKube   6 天前
    我们这边的微服务模块都慢慢用 go 重写了。云原生时代还是用 Go 吧,Java 的内存占用太夸张了
        40
    xinyewdz   6 天前
    使用 jar 启动的,都是使用微服务。每个 jar 提供的服务不多的。你应该是把一个超级大的项目,打包为一个 jar。内存占用肯定大了。
        41
    jlkm2010   6 天前
    25 楼正解
        42
    genjigjj   6 天前
    docker 了解下
        43
    bk201   6 天前
    你容器配置中有没限制 jvm 内存占用?而 jar 运行时候限制内存占用了吗?内嵌跑容器,外置也一样跑容器,有什么区别?
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   3579 人在线   最高记录 4019   ·  
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.1 · 26ms · UTC 08:17 · PVG 16:17 · LAX 00:17 · JFK 03:17
    ♥ Do have faith in what you're doing.
    沪ICP备16043287号-1