As described in that article, there are cases where the Netty native transport doesn't ad much value. However, when you do need it, you really do need it. The easiest cases you need it are when you are handling 100K+ connections on a single machine, or need to use Unix Domain Sockets.
If not those cases, it still is slightly better than the default poller. OpenJDK uses epoll, but not in edge triggered mode like Netty. When handling lots of network events at a time, Netty may wish to not get notified of each one. For example, if you have lots of sockets in your pollset, many of them may become writable or readable. If your application is not ready to read or write though, then being woken up each time you poll is wasteful. You *could* remove the fd from the pollset in such a case, but that would be expensive in terms of JNI calls.
Also, the JDK creates a fair amount of garbage when polling. The native transport avoids garbage creation.
As for how it applies to gRPC? I think the two main benefits are the high connection count and low garbage creation. gRPC Java uses a single thread for each connection (though threads may have multiple connections). This means that effectively gRPC is single threaded at that point. The article is right though, most of the reasons to use epoll are for more exotic threading schemes.