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

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

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

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

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

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