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

2022-07-20 11:46:45 +08:00
 Renco

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

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

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

1281 次点击
所在节点    程序员
11 条回复
dcsuibian
2022-07-20 11:51:50 +08:00
图看不见

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

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

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

不设为 null ,调用 100 次 gc 都没用🐶
nothingistrue
2022-07-20 12:21:04 +08:00
不贴代码,能看个卵卵。看这情形,很有可能你接口调用弄得单例或共享 Bean ,耗内存的变量用了没释放。
Jooooooooo
2022-07-20 12:38:31 +08:00
@blueskea 这个只是文档上这么写而已, 你试试就知道, 调用 system.gc 基本都会执行的. (至少我没遇到过不执行的情况
crayygy
2022-07-20 12:54:01 +08:00
10w 条数据从内存角度来看不是很大,在没人使用这些内存以后会被标记为可回收,下一次 GC 的时候会被回收掉。
如果从手动管理内存的角度( C/C++/Rust )来看的话不是很合理,但从 GC 语言的角度来看没毛病,内存就是这样用的,这甚至都不是内存泄漏。
urnoob
2022-07-20 15:40:31 +08:00
9 成原因是你自己代码问题
1 成原因是转换后的 java 对象太大,直接在 old 区了,mix GC 或者 fullGC 时会释放。完全不需要去管。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/867496

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX