试图了解Java中的垃圾回收

时间:2019-05-12 08:49:19

标签: java collections garbage-collection garbage

尝试通过以下代码了解GC

/** 
* Hire an Employee 
* @param {org.example.basic.HireEmployee} hire - the hire 
* @transaction 
*/

async function hireEmployee(hire) {
    let job = hire.job;
    if (job.state !== 'OPEN') {
        throw new Error('This Job is Closed and Someone is Already Hired');
    }

    job.state = 'ON_LIVE';  
    let lowestOffer = null;
    let employee = null;
    let employer =null;

    if (job.offers && job.offers.length > 0) {
        // sort the bids by bidPrice
        job.offers.sort(function(a, b) {
            return (a.bidPrice - b.bidPrice);
        });
        lowestOffer = job.offers[0];
        if (lowestOffer.bidPrice >= 5 ) {
            // mark the job as Hired
            job.state = 'HIRED';
            let employer = job.employer;
            let employee = lowestOffer.member;

            console.log('#### employer balance before: ' + employer.credit);
            employer.credit -= lowestOffer.bidPrice;
            console.log('#### employer balance after: ' + employer.credit);
            // update the balance of the buyer
            console.log('#### Employee balance before: ' + employee.credit);
            employee.credit += lowestOffer.bidPrice;
            console.log('#### buyer balance after: ' + employee.credit);
            // mark the hire employee
            job.hiredemployee = employee;

            job.offers = null;
        }
    }

     // save the bid
    const jobRegistry = await getAssetRegistry('org.example.basic.Job');
    await jobRegistry.update(job);

    if (job.state === 'HIRED') {
        // save the buyer
        const memberRegistry = await getParticipantRegistry('org.example.basic.Member');
        await memberRegistry.update(employee);

        const userRegistry = await getParticipantRegistry('org.example.basic.Employer');
        await userRegistry.update(employer);
    }


}

由于正在将随机双精度对象创建到列表中,所以我期望发生内存不足错误,并且堆会被填充。

但是我看到我的GC正在清理,幸存空间中只有约1Mb的数据保留。

以32MB的堆大小运行jvm,并将GC的占用百分比设置为30%。

任何人都可以对此行为做更多的解释。enter image description here

2 个答案:

答案 0 :(得分:3)

首先,您没有出现OutOfMemoryError,因为代码中的对象创建得非常慢(每200毫秒)。尝试删除sleep代码片段。

第二,如果您的GC清除了幸存者空间中的数据,这并不意味着GC会从内存中删除该对象。这意味着,GC将这些对象移至了上一代,因为它们在多个垃圾回收中幸免于难。您会看到,旧一代的大小只会增加,并且在那里没有发生垃圾收集。

enter image description here

当堆大小将被填充时,GC会尝试清理对象(您会在GC时间表上看到经常波动的信息),但是这种尝试不会成功,因为它不会删除任何对象。随着时间的流逝,您将收到OME。

我认为,如果您删除sleep代码段并等待足够的时间,您将收到OME。

要获得更快的结果,可以减小堆大小。

答案 1 :(得分:0)

每当您充满伊甸园空间时,次要GC就会运行,并将活动对象转移给幸存者。经过一番迭代后,长寿的幸存者对象被转移到旧的代空间中。

在您的情况下,每当伊甸园空间用完一定百分比并且旧一代的大小随时间增加时,次要GC就会运行。您可以在图中找到它。

删除睡眠间隔,它将为您提供更清晰的视图。另外,您可以配置堆大小以进行更好的分析。

要了解更多信息,请参阅 https://www.journaldev.com/2856/java-jvm-memory-model-memory-management-in-java