/*
* Copyright 2015 Odnoklassniki Ltd, Mail.Ru Group
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package one.nio.mem;
import java.util.Random;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLongArray;
public class MallocTest extends Thread {
private static final int ARRAY_LENGTH = 16000000;
private static final int MIN_LENGTH = 1500000;
private static final int MAX_LENGTH = 15000000;
private static final int AVG_SIZE = 140;
private static final int THREAD_COUNT = 4;
private static final int DELAY = 200;
private static final MallocMT malloc = new MallocMT((long) (1.1 * AVG_SIZE * ARRAY_LENGTH));
private static final AtomicLongArray addresses = new AtomicLongArray(ARRAY_LENGTH);
private static final AtomicInteger count = new AtomicInteger();
private static volatile boolean grow = true;
@Override
public void run() {
Random random = new Random();
for (;;) {
int index = random.nextInt(ARRAY_LENGTH);
if (grow) {
int bytes = random.nextInt(AVG_SIZE * 2);
allocate(index, bytes);
} else {
free(index);
}
}
}
private void allocate(int index, int bytes) {
if (addresses.compareAndSet(index, 0, -1)) {
long address = malloc.malloc(bytes);
addresses.set(index, address);
count.incrementAndGet();
}
}
private void free(int index) {
long address = addresses.get(index);
if (address > 0 && addresses.compareAndSet(index, address, 0)) {
malloc.free(address);
count.decrementAndGet();
}
}
public static void main(String[] args) throws Exception {
Thread[] threads = new Thread[THREAD_COUNT];
for (int i = 0; i < THREAD_COUNT; i++) {
threads[i] = new MallocTest();
}
for (Thread thread : threads) {
thread.start();
}
int prevCount = 0;
for (;;) {
int currentCount = count.get();
int delta = Math.abs(currentCount - prevCount);
prevCount = currentCount;
System.out.printf("count = %d (%d / ms), free = %d MB, %s\n",
currentCount,
delta / DELAY,
malloc.getFreeMemory() / (1024*1024),
grow ? "grow" : "shrink");
if (currentCount < MIN_LENGTH) {
grow = true;
malloc.verify();
} else if (currentCount > MAX_LENGTH) {
grow = false;
malloc.verify();
}
sleep(DELAY);
}
}
}