java首次遇到堆空间错误服务器数据记录器

java首次遇到堆空间错误服务器数据记录器,java,jdbc,heap,heap-memory,Java,Jdbc,Heap,Heap Memory,我构建了我的第一个Java程序,它构建在。这可能重要,也可能不重要。我刚刚用几个新类扩展了主要的API类 该程序正在向远程服务器进行数据查询。当服务器响应时,我将接收到的数据记录到本地MySQL数据库中。一旦程序完成记录数据,程序将发出下一个数据请求 在发出几百个服务器请求后,让程序运行一段时间后,我遇到了一个问题。我将看到此错误,然后程序不会继续执行: java.lang.OutOfMemoryError: Java heap space 我做了一些研究,从我所读到的,我得出结论,这个程序正

我构建了我的第一个Java程序,它构建在。这可能重要,也可能不重要。我刚刚用几个新类扩展了主要的API类

该程序正在向远程服务器进行数据查询。当服务器响应时,我将接收到的数据记录到本地MySQL数据库中。一旦程序完成记录数据,程序将发出下一个数据请求

在发出几百个服务器请求后,让程序运行一段时间后,我遇到了一个问题。我将看到此错误,然后程序不会继续执行:

java.lang.OutOfMemoryError: Java heap space
我做了一些研究,从我所读到的,我得出结论,这个程序正在创造许多新的变量,而不是破坏旧的毫无价值的变量。由于我正在使用Netbeans进行开发,因此我使用了来检查情况是否如此。如图所示:

运行程序一段时间后,越来越多的内存被
Byte
占用。看来我的理论还是正确的

我真的不知道从这里到哪里去。没有对类或特定变量的引用,只有变量类型。我们如何确定问题的根源

更新

我纠正了BigMike在评论中提到的一个具体问题。以前,我在JDBC MySQL连接器API中创建了许多语句,我调用了
.execute()
来执行这些语句,但我没有用
.close()
来关闭语句

我确保在每次执行后添加
语句.close()
调用,现在程序运行得更好了。通过查看该程序的RAM使用情况,似乎解决了问题。我也不再看到
Java堆空间
错误,这很好


谢谢

很难简单地说什么是错的

这可能与您正在打开的流有关,这些流在您不再需要它们时不会关闭。 仔细检查分配资源(从文件、数据库等读取)的方法,特别是当它们将数据读入流时,并确保在finally子句中关闭这些流

除此之外,您还可以尝试分析更频繁调用的方法等,以尝试将问题缩小到代码的特定部分

我找到了一个网站,它合理地解释了垃圾收集的工作原理,以及导致OutOfMemory错误的原因:


如果您通读一遍,就会发现有一个特定的引用指向对象[]和字节[]的高分配,这可能为您指明了正确的方向。

一般来说,这是由于以下两个原因之一:

  • 应用程序中存在内存泄漏,因此应用程序无法释放垃圾收集项,导致JVM随着时间的推移内存不足

  • 应用程序尝试了一次性操作,该操作需要的内存超过可用内存,导致JVM因该操作而内存不足

  • 由于您的输出似乎表明大量内存被100多万个小字节数组占用,因此我猜测#1可能是罪魁祸首;但是,要验证这一点,请重新启动应用程序并观察其内存消耗情况。它会上下波动,但实际上你只需要观察消费趋势。如果平均消耗量持续攀升,则表示内存泄漏

    为了解决这个问题,您通常需要源代码,并且需要找到代码中创建、使用和“存储”麻烦对象的部分,这些对象的使用时间远远超过了上次使用它们的时间。解决方案是更正代码,使其不再存储。哈希映射、列表和其他集合通常是内存泄漏问题的帮凶

    如果缺少源代码,您可以尝试测量内存消耗的趋势,并安排应用程序的关闭和重新启动,以有效地“重置时钟”,从而选择停机时间,而不是看着应用程序为您选择

    如果是一次性操作(不太可能考虑您的数据),那么在触发事件发生之前,您不会看到内存消耗的上升趋势。在这种情况下,通过访问源代码,您应该保护您的应用程序不处理超出正常操作参数的数据。例如,从网络读取消息通常只需要几KB,但在特殊情况下,客户端可能会永久传输。在这种情况下,如果超过最大消息大小限制10 MB,请停止消息处理并抛出错误消息

    在后一种情况下,如果无法访问源代码,唯一的希望是识别传入的干扰,查找错误传输的源,并尝试对其进行操作以防止输出过载


    如何使用这些技术有很多不同之处,但现在你有了一些想法。

    你有100万字节[](字节数组),也许你没有发布一些东西。IB API似乎使用套接字发送数据,也许你需要在每次操作后“释放”资源。我不知道那个api,所以这只是猜测。还请检查db日志代码中的实际结束语句。记录的每一行都使用相同的语句进行日志记录。我从不“关闭”它,只是用一个新字符串重新定义语句变量……所以您只创建一次语句,然后多次使用statement.execute(),而不使用statement.close()?添加一个close();)有关更多信息,请参阅。谢谢。我对Java还是相当陌生的。我一直在做一些
    尝试{}catch{}
    的事情来处理异常,但我从来没有最后放入
    。我将更多地关注流。更新了一个链接