V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Renco
V2EX  ›  程序员

Java 的内存回收机制是怎么回收的,一个接口调用会拉 10w 条数据库数据到内存里,接口执行结束后,内存依旧没有释放。

  •  
  •   Renco · 2022-07-20 11:46:45 +08:00 · 1268 次点击
    这是一个创建于 639 天前的主题,其中的信息可能已经有所发展或是发生改变。

    在下一次接口调用的时候,GC 会释放一次内存。然后接口执行结束后依旧没有释放内存,只有等到下一次调用接口的时候才会释放,合理么这个。

    ![]( https://renco-pic.oss-cn-hangzhou.aliyuncs.com/pic_bed/QQ 图片 20220720114456.png)

    最前面前面是项目刚启动,两次起伏是两次接口调用的时候。

    dcsuibian
        1
    dcsuibian  
       2022-07-20 11:51:50 +08:00
    图看不见

    由 jvm 自己决定的,如果你内存够,他大概就不回收(回收也是有代价的嘛)。
    你可以建议他回收一下,他可能听,也可能不听。
    带 GC 的语言好像都差不多。
    Jooooooooo
        2
    Jooooooooo  
       2022-07-20 11:52:42 +08:00
    满了才回收, 如果你希望手动触发的话, 调用一下 system.gc 就行.
    blueskea
        4
    blueskea  
       2022-07-20 12:06:36 +08:00 via Android
    @Jooooooooo 补充一下,调用 system.gc 功能如 1 楼所说“你可以建议他回收一下,他可能听,也可能不听。”
    gam2046
        5
    gam2046  
       2022-07-20 12:12:49 +08:00
    内存就是拿来用的,gc 可能还需要暂停程序,这是比较重的操作。如果因为内存不释放,导致其他应用无法正常启动,应当在启动 Java 时添加相关参数,-Xmx 以限制最大使用的内存。

    原则上开发人员并不需要关心 gc ,只管用就行了。想要自己严格把控内存的,可以采用 cpp 那种手动申请、释放的语言。
    mrsatangel
        6
    mrsatangel  
       2022-07-20 12:14:24 +08:00
    一般来说 GC 触发的条件要么是某个 generation 或者整个堆的使用率达到了阈值,要么是 allocation failure 。从 gc 日志可以看到具体的触发原因。至于你这种情况,通常是调用接口分配了一些内存,但是没有达到 generation 的阈值,所以内存没有在调用完成后立刻回收。

    - “这合理吗?”
    合理,从 GC 角度来看,并不知道你下一次会分配多大的内存。如果 eagerly gc 反而会对性能造成负面影响。
    xiangyuecn
        7
    xiangyuecn  
       2022-07-20 12:15:56 +08:00
    为什么下次进接口,才释放了?想过没有

    不设为 null ,调用 100 次 gc 都没用🐶
    nothingistrue
        8
    nothingistrue  
       2022-07-20 12:21:04 +08:00
    不贴代码,能看个卵卵。看这情形,很有可能你接口调用弄得单例或共享 Bean ,耗内存的变量用了没释放。
    Jooooooooo
        9
    Jooooooooo  
       2022-07-20 12:38:31 +08:00
    @blueskea 这个只是文档上这么写而已, 你试试就知道, 调用 system.gc 基本都会执行的. (至少我没遇到过不执行的情况
    crayygy
        10
    crayygy  
       2022-07-20 12:54:01 +08:00 via iPhone
    10w 条数据从内存角度来看不是很大,在没人使用这些内存以后会被标记为可回收,下一次 GC 的时候会被回收掉。
    如果从手动管理内存的角度( C/C++/Rust )来看的话不是很合理,但从 GC 语言的角度来看没毛病,内存就是这样用的,这甚至都不是内存泄漏。
    urnoob
        11
    urnoob  
       2022-07-20 15:40:31 +08:00
    9 成原因是你自己代码问题
    1 成原因是转换后的 java 对象太大,直接在 old 区了,mix GC 或者 fullGC 时会释放。完全不需要去管。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2786 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 11:37 · PVG 19:37 · LAX 04:37 · JFK 07:37
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.