mirror of
https://github.com/openjdk/jdk.git
synced 2026-05-11 05:59:52 +00:00
8024718: Metaspace performance counters and memory pools should report the same data
Reviewed-by: stefank, dholmes, coleenp
This commit is contained in:
parent
c00f905a5f
commit
2cab7ea037
@ -65,26 +65,25 @@ class MetaspacePerfCounters: public CHeapObj<mtInternal> {
|
||||
|
||||
MetaspacePerfCounters* MetaspaceCounters::_perf_counters = NULL;
|
||||
|
||||
size_t MetaspaceCounters::calculate_capacity() {
|
||||
// The total capacity is the sum of
|
||||
// 1) capacity of Metachunks in use by all Metaspaces
|
||||
// 2) unused space at the end of each Metachunk
|
||||
// 3) space in the freelist
|
||||
size_t total_capacity = MetaspaceAux::allocated_capacity_bytes()
|
||||
+ MetaspaceAux::free_bytes() + MetaspaceAux::free_chunks_total_bytes();
|
||||
return total_capacity;
|
||||
size_t MetaspaceCounters::used() {
|
||||
return MetaspaceAux::allocated_used_bytes();
|
||||
}
|
||||
|
||||
size_t MetaspaceCounters::capacity() {
|
||||
return MetaspaceAux::committed_bytes();
|
||||
}
|
||||
|
||||
size_t MetaspaceCounters::max_capacity() {
|
||||
return MetaspaceAux::reserved_bytes();
|
||||
}
|
||||
|
||||
void MetaspaceCounters::initialize_performance_counters() {
|
||||
if (UsePerfData) {
|
||||
assert(_perf_counters == NULL, "Should only be initialized once");
|
||||
|
||||
size_t min_capacity = MetaspaceAux::min_chunk_size_bytes();
|
||||
size_t capacity = calculate_capacity();
|
||||
size_t max_capacity = MetaspaceAux::reserved_bytes();
|
||||
size_t used = MetaspaceAux::allocated_used_bytes();
|
||||
|
||||
_perf_counters = new MetaspacePerfCounters("metaspace", min_capacity, capacity, max_capacity, used);
|
||||
size_t min_capacity = 0;
|
||||
_perf_counters = new MetaspacePerfCounters("metaspace", min_capacity,
|
||||
capacity(), max_capacity(), used());
|
||||
}
|
||||
}
|
||||
|
||||
@ -92,31 +91,29 @@ void MetaspaceCounters::update_performance_counters() {
|
||||
if (UsePerfData) {
|
||||
assert(_perf_counters != NULL, "Should be initialized");
|
||||
|
||||
size_t capacity = calculate_capacity();
|
||||
size_t max_capacity = MetaspaceAux::reserved_bytes();
|
||||
size_t used = MetaspaceAux::allocated_used_bytes();
|
||||
|
||||
_perf_counters->update(capacity, max_capacity, used);
|
||||
_perf_counters->update(capacity(), max_capacity(), used());
|
||||
}
|
||||
}
|
||||
|
||||
MetaspacePerfCounters* CompressedClassSpaceCounters::_perf_counters = NULL;
|
||||
|
||||
size_t CompressedClassSpaceCounters::calculate_capacity() {
|
||||
return MetaspaceAux::allocated_capacity_bytes(_class_type) +
|
||||
MetaspaceAux::free_bytes(_class_type) +
|
||||
MetaspaceAux::free_chunks_total_bytes(_class_type);
|
||||
size_t CompressedClassSpaceCounters::used() {
|
||||
return MetaspaceAux::allocated_used_bytes(Metaspace::ClassType);
|
||||
}
|
||||
|
||||
size_t CompressedClassSpaceCounters::capacity() {
|
||||
return MetaspaceAux::committed_bytes(Metaspace::ClassType);
|
||||
}
|
||||
|
||||
size_t CompressedClassSpaceCounters::max_capacity() {
|
||||
return MetaspaceAux::reserved_bytes(Metaspace::ClassType);
|
||||
}
|
||||
|
||||
void CompressedClassSpaceCounters::update_performance_counters() {
|
||||
if (UsePerfData && UseCompressedClassPointers) {
|
||||
assert(_perf_counters != NULL, "Should be initialized");
|
||||
|
||||
size_t capacity = calculate_capacity();
|
||||
size_t max_capacity = MetaspaceAux::reserved_bytes(_class_type);
|
||||
size_t used = MetaspaceAux::allocated_used_bytes(_class_type);
|
||||
|
||||
_perf_counters->update(capacity, max_capacity, used);
|
||||
_perf_counters->update(capacity(), max_capacity(), used());
|
||||
}
|
||||
}
|
||||
|
||||
@ -126,12 +123,9 @@ void CompressedClassSpaceCounters::initialize_performance_counters() {
|
||||
const char* ns = "compressedclassspace";
|
||||
|
||||
if (UseCompressedClassPointers) {
|
||||
size_t min_capacity = MetaspaceAux::min_chunk_size_bytes();
|
||||
size_t capacity = calculate_capacity();
|
||||
size_t max_capacity = MetaspaceAux::reserved_bytes(_class_type);
|
||||
size_t used = MetaspaceAux::allocated_used_bytes(_class_type);
|
||||
|
||||
_perf_counters = new MetaspacePerfCounters(ns, min_capacity, capacity, max_capacity, used);
|
||||
size_t min_capacity = 0;
|
||||
_perf_counters = new MetaspacePerfCounters(ns, min_capacity, capacity(),
|
||||
max_capacity(), used());
|
||||
} else {
|
||||
_perf_counters = new MetaspacePerfCounters(ns, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
@ -25,13 +25,15 @@
|
||||
#ifndef SHARE_VM_MEMORY_METASPACECOUNTERS_HPP
|
||||
#define SHARE_VM_MEMORY_METASPACECOUNTERS_HPP
|
||||
|
||||
#include "memory/metaspace.hpp"
|
||||
#include "memory/allocation.hpp"
|
||||
|
||||
class MetaspacePerfCounters;
|
||||
|
||||
class MetaspaceCounters: public AllStatic {
|
||||
static MetaspacePerfCounters* _perf_counters;
|
||||
static size_t calculate_capacity();
|
||||
static size_t used();
|
||||
static size_t capacity();
|
||||
static size_t max_capacity();
|
||||
|
||||
public:
|
||||
static void initialize_performance_counters();
|
||||
@ -40,8 +42,9 @@ class MetaspaceCounters: public AllStatic {
|
||||
|
||||
class CompressedClassSpaceCounters: public AllStatic {
|
||||
static MetaspacePerfCounters* _perf_counters;
|
||||
static size_t calculate_capacity();
|
||||
static const Metaspace::MetadataType _class_type = Metaspace::ClassType;
|
||||
static size_t used();
|
||||
static size_t capacity();
|
||||
static size_t max_capacity();
|
||||
|
||||
public:
|
||||
static void initialize_performance_counters();
|
||||
|
||||
@ -260,10 +260,10 @@ MemoryUsage CodeHeapPool::get_memory_usage() {
|
||||
}
|
||||
|
||||
MetaspacePool::MetaspacePool() :
|
||||
MemoryPool("Metaspace", NonHeap, capacity_in_bytes(), calculate_max_size(), true, false) { }
|
||||
MemoryPool("Metaspace", NonHeap, 0, calculate_max_size(), true, false) { }
|
||||
|
||||
MemoryUsage MetaspacePool::get_memory_usage() {
|
||||
size_t committed = align_size_down_(capacity_in_bytes(), os::vm_page_size());
|
||||
size_t committed = MetaspaceAux::committed_bytes();
|
||||
return MemoryUsage(initial_size(), used_in_bytes(), committed, max_size());
|
||||
}
|
||||
|
||||
@ -271,26 +271,19 @@ size_t MetaspacePool::used_in_bytes() {
|
||||
return MetaspaceAux::allocated_used_bytes();
|
||||
}
|
||||
|
||||
size_t MetaspacePool::capacity_in_bytes() const {
|
||||
return MetaspaceAux::allocated_capacity_bytes();
|
||||
}
|
||||
|
||||
size_t MetaspacePool::calculate_max_size() const {
|
||||
return FLAG_IS_CMDLINE(MaxMetaspaceSize) ? MaxMetaspaceSize : max_uintx;
|
||||
return FLAG_IS_CMDLINE(MaxMetaspaceSize) ? MaxMetaspaceSize :
|
||||
MemoryUsage::undefined_size();
|
||||
}
|
||||
|
||||
CompressedKlassSpacePool::CompressedKlassSpacePool() :
|
||||
MemoryPool("Compressed Class Space", NonHeap, capacity_in_bytes(), CompressedClassSpaceSize, true, false) { }
|
||||
MemoryPool("Compressed Class Space", NonHeap, 0, CompressedClassSpaceSize, true, false) { }
|
||||
|
||||
size_t CompressedKlassSpacePool::used_in_bytes() {
|
||||
return MetaspaceAux::allocated_used_bytes(Metaspace::ClassType);
|
||||
}
|
||||
|
||||
size_t CompressedKlassSpacePool::capacity_in_bytes() const {
|
||||
return MetaspaceAux::allocated_capacity_bytes(Metaspace::ClassType);
|
||||
}
|
||||
|
||||
MemoryUsage CompressedKlassSpacePool::get_memory_usage() {
|
||||
size_t committed = align_size_down_(capacity_in_bytes(), os::vm_page_size());
|
||||
size_t committed = MetaspaceAux::committed_bytes(Metaspace::ClassType);
|
||||
return MemoryUsage(initial_size(), used_in_bytes(), committed, max_size());
|
||||
}
|
||||
|
||||
@ -224,7 +224,6 @@ public:
|
||||
|
||||
class MetaspacePool : public MemoryPool {
|
||||
size_t calculate_max_size() const;
|
||||
size_t capacity_in_bytes() const;
|
||||
public:
|
||||
MetaspacePool();
|
||||
MemoryUsage get_memory_usage();
|
||||
@ -232,7 +231,6 @@ class MetaspacePool : public MemoryPool {
|
||||
};
|
||||
|
||||
class CompressedKlassSpacePool : public MemoryPool {
|
||||
size_t capacity_in_bytes() const;
|
||||
public:
|
||||
CompressedKlassSpacePool();
|
||||
MemoryUsage get_memory_usage();
|
||||
|
||||
@ -63,10 +63,12 @@ public:
|
||||
size_t committed() const { return _committed; }
|
||||
size_t max_size() const { return _maxSize; }
|
||||
|
||||
static size_t undefined_size() { return (size_t) -1; }
|
||||
|
||||
inline static jlong convert_to_jlong(size_t val) {
|
||||
// In the 64-bit vm, a size_t can overflow a jlong (which is signed).
|
||||
jlong ret;
|
||||
if (val == (size_t)-1) {
|
||||
if (val == undefined_size()) {
|
||||
ret = -1L;
|
||||
} else {
|
||||
NOT_LP64(ret = val;)
|
||||
|
||||
@ -22,18 +22,15 @@
|
||||
*/
|
||||
|
||||
import java.util.List;
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.lang.management.MemoryManagerMXBean;
|
||||
import java.lang.management.MemoryPoolMXBean;
|
||||
import java.lang.management.MemoryUsage;
|
||||
|
||||
import java.lang.management.RuntimeMXBean;
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.lang.management.*;
|
||||
import com.oracle.java.testlibrary.*;
|
||||
import static com.oracle.java.testlibrary.Asserts.*;
|
||||
|
||||
/* @test TestMetaspaceMemoryPool
|
||||
* @bug 8000754
|
||||
* @summary Tests that a MemoryPoolMXBeans is created for metaspace and that a
|
||||
* MemoryManagerMXBean is created.
|
||||
* @library /testlibrary
|
||||
* @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-UseCompressedOops TestMetaspaceMemoryPool
|
||||
* @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-UseCompressedOops -XX:MaxMetaspaceSize=60m TestMetaspaceMemoryPool
|
||||
* @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UseCompressedOops -XX:+UseCompressedClassPointers TestMetaspaceMemoryPool
|
||||
@ -42,35 +39,18 @@ import java.lang.management.ManagementFactory;
|
||||
public class TestMetaspaceMemoryPool {
|
||||
public static void main(String[] args) {
|
||||
verifyThatMetaspaceMemoryManagerExists();
|
||||
verifyMemoryPool(getMemoryPool("Metaspace"), isFlagDefined("MaxMetaspaceSize"));
|
||||
|
||||
if (runsOn64bit()) {
|
||||
if (usesCompressedOops()) {
|
||||
boolean isMetaspaceMaxDefined = InputArguments.containsPrefix("-XX:MaxMetaspaceSize");
|
||||
verifyMemoryPool(getMemoryPool("Metaspace"), isMetaspaceMaxDefined);
|
||||
|
||||
if (Platform.is64bit()) {
|
||||
if (InputArguments.contains("-XX:+UseCompressedOops")) {
|
||||
MemoryPoolMXBean cksPool = getMemoryPool("Compressed Class Space");
|
||||
verifyMemoryPool(cksPool, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean runsOn64bit() {
|
||||
return !System.getProperty("sun.arch.data.model").equals("32");
|
||||
}
|
||||
|
||||
private static boolean usesCompressedOops() {
|
||||
return isFlagDefined("+UseCompressedOops");
|
||||
}
|
||||
|
||||
private static boolean isFlagDefined(String name) {
|
||||
RuntimeMXBean runtimeMxBean = ManagementFactory.getRuntimeMXBean();
|
||||
List<String> args = runtimeMxBean.getInputArguments();
|
||||
for (String arg : args) {
|
||||
if (arg.startsWith("-XX:" + name)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static void verifyThatMetaspaceMemoryManagerExists() {
|
||||
List<MemoryManagerMXBean> managers = ManagementFactory.getMemoryManagerMXBeans();
|
||||
for (MemoryManagerMXBean manager : managers) {
|
||||
@ -95,32 +75,19 @@ public class TestMetaspaceMemoryPool {
|
||||
|
||||
private static void verifyMemoryPool(MemoryPoolMXBean pool, boolean isMaxDefined) {
|
||||
MemoryUsage mu = pool.getUsage();
|
||||
assertDefined(mu.getInit(), "init");
|
||||
assertDefined(mu.getUsed(), "used");
|
||||
assertDefined(mu.getCommitted(), "committed");
|
||||
long init = mu.getInit();
|
||||
long used = mu.getUsed();
|
||||
long committed = mu.getCommitted();
|
||||
long max = mu.getMax();
|
||||
|
||||
assertGTE(init, 0L);
|
||||
assertGTE(used, init);
|
||||
assertGTE(committed, used);
|
||||
|
||||
if (isMaxDefined) {
|
||||
assertDefined(mu.getMax(), "max");
|
||||
assertGTE(max, committed);
|
||||
} else {
|
||||
assertUndefined(mu.getMax(), "max");
|
||||
}
|
||||
}
|
||||
|
||||
private static void assertDefined(long value, String name) {
|
||||
assertTrue(value != -1, "Expected " + name + " to be defined");
|
||||
}
|
||||
|
||||
private static void assertUndefined(long value, String name) {
|
||||
assertEquals(value, -1, "Expected " + name + " to be undefined");
|
||||
}
|
||||
|
||||
private static void assertEquals(long actual, long expected, String msg) {
|
||||
assertTrue(actual == expected, msg);
|
||||
}
|
||||
|
||||
private static void assertTrue(boolean condition, String msg) {
|
||||
if (!condition) {
|
||||
throw new RuntimeException(msg);
|
||||
assertEQ(max, -1L);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -61,10 +61,15 @@ public class TestMetaspacePerfCounters {
|
||||
}
|
||||
|
||||
private static void checkPerfCounters(String ns) throws Exception {
|
||||
for (PerfCounter counter : countersInNamespace(ns)) {
|
||||
String msg = "Expected " + counter.getName() + " to be larger than 0";
|
||||
assertGT(counter.longValue(), 0L, msg);
|
||||
}
|
||||
long minCapacity = getMinCapacity(ns);
|
||||
long maxCapacity = getMaxCapacity(ns);
|
||||
long capacity = getCapacity(ns);
|
||||
long used = getUsed(ns);
|
||||
|
||||
assertGTE(minCapacity, 0L);
|
||||
assertGTE(used, minCapacity);
|
||||
assertGTE(capacity, used);
|
||||
assertGTE(maxCapacity, capacity);
|
||||
}
|
||||
|
||||
private static void checkEmptyPerfCounters(String ns) throws Exception {
|
||||
@ -75,12 +80,10 @@ public class TestMetaspacePerfCounters {
|
||||
}
|
||||
|
||||
private static void checkUsedIncreasesWhenLoadingClass(String ns) throws Exception {
|
||||
PerfCounter used = PerfCounters.findByName(ns + ".used");
|
||||
|
||||
long before = used.longValue();
|
||||
long before = getUsed(ns);
|
||||
fooClass = compileAndLoad("Foo", "public class Foo { }");
|
||||
System.gc();
|
||||
long after = used.longValue();
|
||||
long after = getUsed(ns);
|
||||
|
||||
assertGT(after, before);
|
||||
}
|
||||
@ -101,4 +104,20 @@ public class TestMetaspacePerfCounters {
|
||||
private static boolean isUsingCompressedClassPointers() {
|
||||
return Platform.is64bit() && InputArguments.contains("-XX:+UseCompressedClassPointers");
|
||||
}
|
||||
|
||||
private static long getMinCapacity(String ns) throws Exception {
|
||||
return PerfCounters.findByName(ns + ".minCapacity").longValue();
|
||||
}
|
||||
|
||||
private static long getCapacity(String ns) throws Exception {
|
||||
return PerfCounters.findByName(ns + ".capacity").longValue();
|
||||
}
|
||||
|
||||
private static long getMaxCapacity(String ns) throws Exception {
|
||||
return PerfCounters.findByName(ns + ".maxCapacity").longValue();
|
||||
}
|
||||
|
||||
private static long getUsed(String ns) throws Exception {
|
||||
return PerfCounters.findByName(ns + ".used").longValue();
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import java.util.List;
|
||||
import java.lang.management.*;
|
||||
|
||||
import com.oracle.java.testlibrary.*;
|
||||
import static com.oracle.java.testlibrary.Asserts.*;
|
||||
|
||||
/* @test TestPerfCountersAndMemoryPools
|
||||
* @bug 8023476
|
||||
* @summary Tests that a MemoryPoolMXBeans and PerfCounters for metaspace
|
||||
* report the same data.
|
||||
* @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-UseCompressedOops -XX:-UseCompressedKlassPointers -XX:+UseSerialGC -XX:+UsePerfData TestPerfCountersAndMemoryPools
|
||||
* @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UseCompressedOops -XX:+UseCompressedKlassPointers -XX:+UseSerialGC -XX:+UsePerfData TestPerfCountersAndMemoryPools
|
||||
*/
|
||||
public class TestPerfCountersAndMemoryPools {
|
||||
public static void main(String[] args) throws Exception {
|
||||
checkMemoryUsage("Metaspace", "sun.gc.metaspace");
|
||||
|
||||
if (InputArguments.contains("-XX:+UseCompressedKlassPointers") && Platform.is64bit()) {
|
||||
checkMemoryUsage("Compressed Class Space", "sun.gc.compressedclassspace");
|
||||
}
|
||||
}
|
||||
|
||||
private static MemoryUsage getMemoryUsage(String memoryPoolName) {
|
||||
List<MemoryPoolMXBean> pools = ManagementFactory.getMemoryPoolMXBeans();
|
||||
for (MemoryPoolMXBean pool : pools) {
|
||||
if (pool.getName().equals(memoryPoolName)) {
|
||||
return pool.getUsage();
|
||||
}
|
||||
}
|
||||
|
||||
throw new RuntimeException("Excpted to find a memory pool with name " +
|
||||
memoryPoolName);
|
||||
}
|
||||
|
||||
private static void checkMemoryUsage(String memoryPoolName, String perfNS)
|
||||
throws Exception {
|
||||
// Need to do a gc before each comparison to update the perf counters
|
||||
|
||||
System.gc();
|
||||
MemoryUsage mu = getMemoryUsage(memoryPoolName);
|
||||
assertEQ(getMinCapacity(perfNS), mu.getInit());
|
||||
|
||||
System.gc();
|
||||
mu = getMemoryUsage(memoryPoolName);
|
||||
assertEQ(getUsed(perfNS), mu.getUsed());
|
||||
|
||||
System.gc();
|
||||
mu = getMemoryUsage(memoryPoolName);
|
||||
assertEQ(getCapacity(perfNS), mu.getCommitted());
|
||||
}
|
||||
|
||||
private static long getMinCapacity(String ns) throws Exception {
|
||||
return PerfCounters.findByName(ns + ".minCapacity").longValue();
|
||||
}
|
||||
|
||||
private static long getCapacity(String ns) throws Exception {
|
||||
return PerfCounters.findByName(ns + ".capacity").longValue();
|
||||
}
|
||||
|
||||
private static long getUsed(String ns) throws Exception {
|
||||
return PerfCounters.findByName(ns + ".used").longValue();
|
||||
}
|
||||
}
|
||||
@ -41,6 +41,9 @@ public class InputArguments {
|
||||
/**
|
||||
* Returns true if {@code arg} is an input argument to the VM.
|
||||
*
|
||||
* This is useful for checking boolean flags such as -XX:+UseSerialGC or
|
||||
* -XX:-UsePerfData.
|
||||
*
|
||||
* @param arg The name of the argument.
|
||||
* @return {@code true} if the given argument is an input argument,
|
||||
* otherwise {@code false}.
|
||||
@ -48,4 +51,26 @@ public class InputArguments {
|
||||
public static boolean contains(String arg) {
|
||||
return args.contains(arg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if {@code prefix} is the start of an input argument to the
|
||||
* VM.
|
||||
*
|
||||
* This is useful for checking if flags describing a quantity, such as
|
||||
* -XX:+MaxMetaspaceSize=100m, is set without having to know the quantity.
|
||||
* To check if the flag -XX:MaxMetaspaceSize is set, use
|
||||
* {@code InputArguments.containsPrefix("-XX:MaxMetaspaceSize")}.
|
||||
*
|
||||
* @param prefix The start of the argument.
|
||||
* @return {@code true} if the given argument is the start of an input
|
||||
* argument, otherwise {@code false}.
|
||||
*/
|
||||
public static boolean containsPrefix(String prefix) {
|
||||
for (String arg : args) {
|
||||
if (arg.startsWith(prefix)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user