简体   繁体   English

垃圾回收行为

[英]Garbage Collection behavior

During start up of my application, database is queried, objects are created (from the result of the query) and are inserted in aa Arraylist. 在我的应用程序启动期间,查询数据库,创建对象(根据查询结果),并将其插入Arraylist中。 The arraylist is later looped and another data structure is created out of it. 稍后将arraylist循环,并从中创建另一个数据结构。 The arraylist (which is huge in size) is later garbage collected. 该arraylist(大小巨大)后来被垃圾收集。 My question is, is this a strain on a garbage collector to collect such a big object at once. 我的问题是,这是否会使垃圾收集器立即收集这么大的对象感到压力。 What if I create a QUEUE data structure instead of arraylist. 如果我创建一个QUEUE数据结构而不是arraylist怎么办。 Reading the object from the queue would make them eligible for GC. 从队列中读取对象将使它们有资格使用GC。 Is that lesser strain on the GC? GC的压力较小吗? I am aware that GC could run anytime and there are no guarantees of it execution. 我知道GC可以随时运行,并且不能保证它可以执行。 More that the timing of execution, what I would like to understand is is it more work for the GC to collect from a contiguous location of memory (arraylist) as against a QUEUE , in which memory allocation is not contiguous? 除了执行时间之外,我想了解的是,GC从内存的连续位置(数组列表)(而不是QUEUE)(内存分配不连续)中收集更多的工作是吗?

is it more work for the GC to collect from a contiguous location of memory (arraylist) as against a QUEUE , in which memory allocation is not contiguous? 与QUEUE相比,GC从内存的连续位置(数组列表)中收集内存是否需要更多工作?

It is more work to clean up a linked list based queue than an ArrayList. 与ArrayList相比,清理基于链表的队列的工作更多。 This is becaume an ArrayList has two objects, the Queue has one object per element. 这是因为ArrayList有两个对象,而Queue每个元素只有一个对象。

If you want to reduce the GC load, process the data as you read it. 如果要减少GC负载,请在读取数据时对其进行处理。 This way you won't need a queue or a list and you might find you have processed all the data by the time it has downloaded. 这样,您就不需要队列或列表,您可能会发现下载时已处理完所有数据。 ie it could be quite a bit faster too. 即它可能会快很多。

The biggest strain here comes from keeping objects, which are "huge in size" in memory. 这里最大的压力来自于保存在内存中“巨大”的对象。 It can cause GC to work more frequently if other objects need to be created on a heap or even lead to "out of memory" exception when the size of your DB and ArrayList increase. 如果需要在堆上创建其他对象,则可能导致GC更加频繁地工作,或者当DB和ArrayList的大小增加时甚至导致“内存不足”异常。

Any solution that would allow you to decrease the size of memory allocated to "huge" objects will help. 任何允许您减少分配给“巨大”对象的内存大小的解决方案都将有所帮助。 If you can build your queue in such a way that queue elements are released fast without waiting for all other objects to be read from a DB, go for it. 如果您可以通过快速释放队列元素而无需等待从数据库读取所有其他对象的方式来构建队列,那就去吧。

As Peter mentioned in his answer, it would be even better to process an object as soon as it was read from a DB without queuing it or adding to a list. 正如Peter在他的回答中提到的,最好是在从数据库中读取对象而不对其进行排队或添加到列表后立即对其进行处理。

One of the possible solutions would be to re-design your data access layer and use ResultSet ( http://docs.oracle.com/javase/7/docs/api/java/sql/ResultSet.html ), which is available in any Java platform that I can think of. 一种可能的解决方案是重新设计您的数据访问层并使用ResultSet( http://docs.oracle.com/javase/7/docs/api/java/sql/ResultSet.html ),该工具可以在我能想到的任何Java平台。 Since ResultSet is kept on a DB side, you can read records one at a time and decrease the strain on your memory significantly. 由于ResultSet保留在DB端,因此您可以一次读取一个记录,从而显着减少了内存负担。

Another approach would be to implement pagination, eg by changing your original query in such a way that only a portion of ListArray is read from a DB at a time. 另一种方法是实现分页,例如,通过更改原始查询,使得一次仅从数据库读取ListArray的一部分来进行分页。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM