Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/359.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在存储Oracle数据库中的数据期间管理JAVA堆大小_Java_Oracle_Memory Management - Fatal编程技术网

在存储Oracle数据库中的数据期间管理JAVA堆大小

在存储Oracle数据库中的数据期间管理JAVA堆大小,java,oracle,memory-management,Java,Oracle,Memory Management,我需要通过循环结果集(Oracle数据库)在内存中存储大量数据 我进行了一些测试,通过使用探查器,我注意到堆大小和使用的堆(即我的数据)之间存在很大的差异。这里有一个例子 为了设置正确的堆大小,我已经看到了可用的JVM参数,但问题是我事先不知道数据将占用多少字节(因为每个测试的数据量可能不同) 通过观察图像中的图形,问题似乎是执行过程中的内存“峰值” 这些峰值是否与提取的行数有关(或者通常与提取的数据有关) 有没有办法通过保持内存几乎不变(这样堆大小就不会过度增加)来避免这种影响 谢谢当然可以

我需要通过循环结果集(Oracle数据库)在内存中存储大量数据

我进行了一些测试,通过使用探查器,我注意到
堆大小
使用的堆
(即我的数据)之间存在很大的差异。这里有一个例子

为了设置正确的堆大小,我已经看到了可用的JVM参数,但问题是我事先不知道数据将占用多少字节(因为每个测试的数据量可能不同)

通过观察图像中的图形,问题似乎是执行过程中的内存“峰值”

这些峰值是否与提取的行数有关(或者通常与提取的数据有关)

有没有办法通过保持内存几乎不变(这样堆大小就不会过度增加)来避免这种影响


谢谢

当然可以限制内存,但这样做没有多大好处。如果这样做,垃圾收集将不得不更频繁地进行,这将导致程序执行速度变慢

这就是Java中垃圾收集的工作方式。如果你有足够的内存,GC将不会被调用。这会给你的应用程序更多的资源(CPU时间)


此外,为了优化内存消耗,您应该检查算法,看看是否可以重用某些对象而不是创建新对象,因为新对象正是蓝线上升的原因。请参见
飞重
和其他用于控制内存消耗的类似模式。

通过查看内存图表,我可以似乎很多数据都是临时性的,可以在某个时候从堆中删除。使用的堆与其总大小的最终比率说明了一切

它似乎是临时数据(例如,来自Oracle
ResultSet
的缓冲数据)生存时间太长或eden空间太小,因此数据从eden和/或幸存者空间移动到旧代空间,在旧代空间中收集数据,这是因为JVM检测到需要在旧代空间上运行GC。当您迭代
结果集
和Oracle时,可能会发生这种情况驱动程序需要从数据库中获取下一个数据块,该数据块可能相当大

此时,我应该详细介绍一下Oracle
ResultSet
缓冲区。它基本上只是堆上的一块字节。根据列数据的不同,它存储为不同于您从
ResultSet
读取的内容。以
java.sql.Timestamp
为例。它存储在缓冲区内这意味着无论何时从
ResultSet
中提取
java.sql.Timestamp
,都需要分配另一个对象。这个对象很可能是您最终想要保留的“最终”对象

我建议根据您的需要调整JVM的GC。也许您可以找出不断收集的数据。尝试调整eden大小,使JVM不需要向旧一代提升太多。您还可以调整JVM根据需要分配的新空间量,以及在检测到使用率和分配大小的差距时如何缩小

您可以找到JVM选项的列表

这些峰值是否与提取的行数有关(或者通常与提取的数据有关)

我猜你指的是蓝峰

蓝色区域表示在任何给定时间点使用的内存,峰值表示垃圾收集器运行的点。如您所见,该线与每个峰值成一定角度向上倾斜,然后垂直下降。这是正常行为

您还将注意到,波峰和波谷的高度都呈上升趋势,这很可能是应用程序内存中数据结构增长的结果

有没有办法通过保持内存几乎不变(这样堆大小就不会过度增加)来避免这种影响

基本上没有。如果蓝线不是锯齿状的,或者峰值较浅且距离较近,这意味着GC运行得更频繁……这对性能不利

基本上,如果您要在内存中构建大数据结构,您需要足够的内存来表示它,再加上一堆额外的空间来放置临时对象,并为垃圾收集器提供空间来完成它需要做的事情


如果您担心应用程序总体上使用了太多内存,那么您需要优化正在构建的内存中数据结构,并检查是否存在任何(其他)内存泄漏


如果你担心java java无法预测Java堆有多大,那么考虑把SQL查询作为计数,然后以计数为基础的堆大小估计开始/重新启动Java应用程序。

哪些峰值是你最大的或所有的?尼古拉斯@所有这些。例如,在上面的图中,如果我能够在执行期间将内存保持在1 GB和1,25 GB之间,那么最终堆的大小可能会更低。