Skip to content
Snippets Groups Projects
Commit a71f8c53 authored by Glauber Costa's avatar Glauber Costa
Browse files

tests: add java reclaim test


This is a test in which two threads compete for resources. One of them will
(hopefully) trigger memory allocations that are served by the heap while the other
will stress the filesystem through reads and/or writes (no mappings).

This is designed to test how well the balloon code works together with the ARC
reclaimer.

There are three main goals I expect OSv to achieve when running this test:

1) When there is no filesystem activity, the balloon should never trigger, and
the ARC cache should be reduced to its minimum
2) When there is no java activity, we should balloon as much as we can, leaving
the memory available to the filesystem (this one is trickier because the IO code
is itself a java application - on purpose - so we eventually have to stop)
3) When both are happening in tandem, the system should stabilize in reasonable
values and not spend useless cycles switching memory back and forth.

Signed-off-by: default avatarGlauber Costa <glommer@cloudius-systems.com>
parent 9bbc86fc
No related branches found
No related tags found
No related merge requests found
......@@ -22,6 +22,8 @@ mgmt = 1
all: $(submake) $(modulemk)
$(call quiet, $(silentant) ant -Dmode=$(mode) -Dout=$(abspath $(out)/tests/bench) \
-e -f tests/bench/build.xml $(if $V,,-q), ANT tests/bench)
$(call quiet, $(silentant) ant -Dmode=$(mode) -Dout=$(abspath $(out)/tests/reclaim) \
-e -f tests/reclaim/build.xml $(if $V,,-q), ANT tests/reclaim)
$(MAKE) -r -C $(dir $(submake)) $@
$(submake) $(modulemk): Makefile
......
......@@ -192,7 +192,7 @@ boost-tests += tests/tst-bsd-tcp1.so
java_tests := tests/hello/Hello.class
tests := tests/tst-pthread.so tests/tst-ramdisk.so
tests += tests/tst-vblk.so tests/bench/bench.jar
tests += tests/tst-vblk.so tests/bench/bench.jar tests/reclaim/reclaim.jar
tests += tests/tst-bsd-evh.so tests/misc-bsd-callout.so
tests += tests/tst-bsd-kthread.so
tests += tests/tst-bsd-taskqueue.so
......
<?xml version="1.0" encoding="UTF-8"?>
<project name="bench" default="dist" basedir=".">
<description>
simple example build file
</description>
<!-- set global properties for this build -->
<property name="src" location="."/>
<property name="build" location="${out}/classes"/>
<property name="dist" location="${out}"/>
<target name="init">
<!-- Create the build directory structure used by compile -->
<mkdir dir="${build}"/>
<mkdir dir="${build}/META-INF"/>
</target>
<target name="compile" depends="init"
description="compile the source " >
<!-- Compile the java code from ${src} into ${build} -->
<javac includeantruntime="false" srcdir="${src}" destdir="${build}"/>
</target>
<target name="dist" depends="compile"
description="generate the distribution" >
<jar jarfile="${dist}/reclaim.jar" basedir="${build}" compress="false">
<fileset dir="${build}"/>
<fileset dir="${src}" includes="test.txt"/>
<manifest>
<attribute name="Main-Class" value="com.cloudiussystems.reclaim.Reclaim"/>
</manifest>
</jar>
</target>
<target name="clean"
description="clean up" >
<!-- Delete the ${build} and ${dist} directory trees -->
<delete dir="${build}"/>
<delete dir="${dist}"/>
</target>
</project>
/*
* Copyright (C) 2014 Cloudius Systems, Ltd.
*
* This work is open source software, licensed under the terms of the
* BSD license as described in the LICENSE file in the top-level directory.
*/
package com.cloudiussystems.reclaim;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
public class FSConsumer {
private JVMConsumer _Jvm;
private ArrayList<ByteBuffer> BList;
private final int page = 2 << 20;
private RandomAccessFile file;
public FSConsumer() {
try {
file = new RandomAccessFile("/tests/reclaim/file", "rw");
} catch (IOException x) {
System.err.format("Error writing to file: %s%n", x);
}
}
public void consume_buffers() {
System.out.println("Consuming " + BList.size() + " buffers...");
System.out.println("Starting file");
int idx = 0;
FileChannel channel;
try {
file.setLength(0);
channel = file.getChannel();
channel.position(0);
} catch (IOException x) {
System.err.format("Error setting up channel for file: %s%n", x);
return;
}
while (!BList.isEmpty()) {
if ((BList.size() % 10) == 0) {
System.out.println("Current size: " + BList.size());
}
ByteBuffer b = BList.remove(0);
try {
while (b.hasRemaining()) {
channel.write(b);
}
} catch (IOException x) {
System.err.format("Error writing to file: %s%n", x);
return;
}
}
System.out.println("Finished write. Reading back...");
try {
long size = file.length();
channel.position(0);
// Make sure the ARC is stressed. Not all writes will.
while (channel.position() < channel.size()) {
ByteBuffer buf = ByteBuffer.allocate(4 << 10);
channel.read(buf);
}
} catch (IOException x) {
System.err.format("Error closing file: %s%n", x);
return;
}
System.out.println("FILE Done");
return;
}
public void consume() {
System.out.println("Consumes the buffers");
consume_buffers();
}
public void set_jvm(JVMConsumer jvm) {
_Jvm = jvm;
BList = _Jvm.BList;
}
}
/*
* Copyright (C) 2014 Cloudius Systems, Ltd.
*
* This work is open source software, licensed under the terms of the
* BSD license as described in the LICENSE file in the top-level directory.
*/
package com.cloudiussystems.reclaim;
import java.util.ArrayList;
import java.nio.ByteBuffer;
public class JVMConsumer {
private FSConsumer _Fs;
// To keep references alive
public ArrayList<ByteBuffer> BList = new ArrayList<ByteBuffer>();
private final int page = 2 << 20;
static long total_memory = Runtime.getRuntime().maxMemory();
public static long printMemory(long missing) {
long free_memory = Runtime.getRuntime().freeMemory();
if ((missing % 10) == 0) {
System.out.println("Free Memory: " + free_memory + ". Total " + total_memory + " (" + (free_memory * 100.00) / total_memory + " %). " + missing + " more to go");
}
return free_memory;
}
public void createBuffers(long buffers) {
for (long i = 0; i < buffers; i++) {
long free_memory = Runtime.getRuntime().freeMemory();
ByteBuffer buf = ByteBuffer.allocate(page);
buf.putLong(free_memory);
BList.add(buf);
printMemory(buffers - i);
}
printMemory(0);
}
public void alloc(long bytes) {
createBuffers(bytes / page);
}
public void set_fs(FSConsumer fs)
{
_Fs = fs;
}
}
/*
* Copyright (C) 2014 Cloudius Systems, Ltd.
*
* This work is open source software, licensed under the terms of the
* BSD license as described in the LICENSE file in the top-level directory.
*/
package com.cloudiussystems.reclaim;
import java.lang.Runtime;
public class Reclaim {
static long memory = Runtime.getRuntime().maxMemory();
public static void main(String[] args) {
JVMConsumer jvm = new JVMConsumer();
FSConsumer fs = new FSConsumer();
System.out.println("Starting reclaimer test. Max Heap: " + memory);
jvm.set_fs(fs);
fs.set_jvm(jvm);
for (int i = 1; i < 10; i++) {
System.out.println("Iteration number " + i);
jvm.alloc(i * memory / 10);
fs.consume();
}
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment