小编Ser*_*nic的帖子

Java进程的内存无限增长,但MemoryMXBean报告稳定的堆和非堆大小

我正在与一个开发在1GB Linux目标系统上运行的Java GUI应用程序的团队合作.

我们遇到的问题是,我们的java进程使用的内存无限增长,直到Linux最终杀死java进程.

我们的堆内存健康稳定.(我们已广泛地分析了我们的堆)我们还使用MemoryMXBean来监视应用程序的非堆内存使用情况,因为我们认为问题可能就在那里.但是,我们看到报告的堆大小+报告的非堆大小保持稳定.

下面是一个示例,说明在我们的目标系统上运行具有1GB RAM的应用程序时的数字(MemoryMXBean报告的堆和非堆,使用Linux的top命令(常驻内存)监视的Java进程使用的总内存):

在启动时:

  • 提交200 MB堆
  • 40 MB非堆已提交
  • java进程使用的320 MB

1天后:

  • 提交200 MB堆
  • 40 MB非堆已提交
  • java进程使用的360 MB

2天后:

  • 提交200 MB堆
  • 40 MB非堆已提交
  • java进程使用的400 MB

上面的数字只是我们系统表现的"清晰"表示,但它们相当准确且接近现实.如您所见,趋势很明显.运行应用程序几周后,由于系统内存不足,Linux系统开始出现问题.事情开始放缓.再过几个小时,Java进程就被杀了.

经过几个月的分析并试图理解这一点,我们仍然处于亏损状态.我觉得很难找到有关此问题的信息,因为大多数讨论最终都会解释堆或其他非堆内存池.(像Metaspace等)

我的问题如下:

  1. 如果你把它分解,java进程使用的内存包括什么?(除了堆和非堆内存池之外)

  2. 哪些其他潜在来源存在内存泄漏?(本机代码?JVM开销?)一般来说哪些是最可能的罪魁祸首?

  3. 如何监控/分析这个内存?堆+非堆外的所有东西目前对我们来说都是一个黑盒子.

任何帮助将不胜感激.

java linux memory memory-leaks

14
推荐指数
1
解决办法
1142
查看次数

lambda /方法引用和泛型的“不兼容类型”编译器错误

我在处理一些旧代码时偶然发现了一个问题,用 lambda 表达式或方法引用替换了几个匿名类。这个问题有点难以用语言解释,但我会尽力而为,并且我还在下面添加了一个简短的示例,尽我所能来说明我的问题。

我的例子包括...

  1. 函数式接口GenericListener接受类型参数 V并具有单个方法“genericCallback(V genericValue)”。

  2. 一个类CallbackProducer,它采用类型参数 T。该类还有一个方法来添加 Integer 类型的 GenericListener。

  3. 一个Main类,它创建 CallbackProducers 并向其中添加 GenericListeners。

当我从 Main 的构造函数运行 CallbackProducer 的 addIntegerListener 方法时,只要我避免指定 CallbackProducer T 的类型,就会收到编译器错误:“不兼容的类型”。

addIntegerListener 方法仅使用 GenericListener 的 V。据我所知,它没有以任何方式使用 CallbackProducer 的 T。

我在 Main 的构造函数中多次调用 addIntegerListener + 注释,其中 3 次调用导致编译器错误。但据我所知(根据 IntelliJ),所有这些都应该是合法的。如果您注释掉对 addIntegerListener 的第 3 个调用,应用程序将编译并运行得很好。

另外,如果 CallbackProducer 不使用泛型,并且我们完全删除了类型参数 T,则对 addIntegerListener 的第 3 次调用将编译。

这种行为有原因吗?我是否误解了什么,或者这是java编译器的弱点或错误?(我目前使用的是java 1.8_51)

预先感谢您的任何澄清!

import javax.swing.*;

public class Main {

    public static void main(final …
Run Code Online (Sandbox Code Playgroud)

java generics lambda compiler-errors method-reference

5
推荐指数
1
解决办法
4296
查看次数