2
* Copyright (C) 2000-2013 Heinz Max Kabutz
4
* See the NOTICE file distributed with this work for additional
5
* information regarding copyright ownership. Heinz Max Kabutz licenses
6
* this file to you under the Apache License, Version 2.0 (the "License");
7
* you may not use this file except in compliance with the License. You may
8
* obtain a copy of the License at
10
* http://www.apache.org/licenses/LICENSE-2.0
12
* Unless required by applicable law or agreed to in writing, software
13
* distributed under the License is distributed on an "AS IS" BASIS,
14
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
* See the License for the specific language governing permissions and
16
* limitations under the License.
19
package com.gs.collections.impl.memory;
21
import java.text.NumberFormat;
23
import com.gs.collections.api.block.function.Function0;
24
import com.gs.collections.api.block.procedure.primitive.IntProcedure;
25
import com.gs.collections.impl.list.Interval;
26
import org.slf4j.Logger;
27
import org.slf4j.LoggerFactory;
29
public final class MemoryTestBench
31
private static final Logger LOGGER = LoggerFactory.getLogger(MemoryTestBench.class);
33
private static final GCAndSleepProcedure GC_AND_SLEEP_PROCEDURE = new GCAndSleepProcedure();
34
private static final Interval GC_INTERVAL = Interval.oneTo(20);
35
private final Class<?> clazz;
37
private MemoryTestBench(Class<?> clazz)
42
public static MemoryTestBench on(Class<?> clazz)
44
return new MemoryTestBench(clazz);
49
* (http://www.javaspecialists.eu/archive/Issue193.html). Used
50
* to estimate memory usage by objects.
52
public long calculateMemoryUsage(Function0<?> factory)
54
// Clean the slate and prep
55
this.forceGCAndSleepMultipleTimes();
56
Object container = factory.value();
57
if (!this.clazz.isInstance(container))
59
throw new RuntimeException();
61
long memory = this.currentUsedMemory();
62
//noinspection UnusedAssignment,ReuseOfLocalVariable
64
this.forceGCAndSleepMultipleTimes();
66
// Calculate memory before creation
67
long memory2 = this.currentUsedMemory();
68
//noinspection UnusedAssignment,ReuseOfLocalVariable
69
container = factory.value();
70
// Get rid of transient garbage
71
this.forceGCAndSleepMultipleTimes();
72
// Calculate new used memory
73
return this.currentUsedMemory() - memory2;
76
private long currentUsedMemory()
78
Runtime runtime = Runtime.getRuntime();
79
return runtime.totalMemory() - runtime.freeMemory();
82
private void forceGCAndSleepMultipleTimes()
84
GC_INTERVAL.forEach(GC_AND_SLEEP_PROCEDURE);
87
public void printContainerMemoryUsage(String category, int size, Function0<?> factory)
89
String memoryUsedInBytes = NumberFormat.getInstance().format(this.calculateMemoryUsage(factory));
90
String sizeFormatted = NumberFormat.getInstance().format(size);
91
LOGGER.info("{} {} size {} bytes {}", category, this.clazz.getName(), sizeFormatted, memoryUsedInBytes);
94
private static class GCAndSleepProcedure implements IntProcedure
97
public void value(int each)
104
catch (InterruptedException e)
106
throw new RuntimeException(e);